I am currently working on an Angular component where I would like to have a dynamic store name, for my ngrx/store(feature module). As a result, I have added an #Input() storeName: string; value to my component. I want to be able to specify the storeName on the html DOM and pass it to the store. That, however, is my precise issue. I am not sure as how to pass an #Input() value from my component to my module.
The idea is:
StoreModule.forFeature('myStoreName', myReducer, {initialState: myInputInitialState}).
so that instead of myStoreName, it can be the #Input value created on the component. Any suggestions are more than welcome. Thank you.
All things considered, I realized what I was doing was an anti-pattern. Even if I would have the option to instantiate a module, with an input value passed through a component(which for reasons of AOT I cannot), those values would ultimately have to be passed elsewhere.
Instead, I did indeed give this component a state feature name that is static. However, this state get's passed elsewhere, when a particular event handler is called. Staying true to what this input component is supposed to be, a temporary state, until user is able to submit, or any other event for that matter. I believe this to be similar for all other situations with dynamic components.
Related
I tend to avoid using class variable as much as possible, likely 99% of my codes are done with state. Always have an impression that, we should avoid using this because React re-render UI when there are change to state or props only.
Recently my colleague started using class variable, for storing some hardcoded value like following. I don't see why we can't store this hardcoded value within state, although the value actually never gets updated in app. And this type of value assigning still works.
this.Arr = [
{ option: 'Product'},
{ option: 'Technical'},
{ option: 'Enquiry'},
{ option: 'Report'},
];
So, should we use class variable in react native? What's your supporting argument here?
Update
After some further readings from the following questions, I came into a conclusion of..
Readings:
ReactJS - What is difference between component state and class variable?
Should a React component use (fixed) values not on state or props?
Conclusion:
As always, keep variable that possibly mutate inside State Variable.
It's fine to store hardcoded value with Class Variable. However, it might make sense to move them to a constant file where you read all the fix value from there.
Using Class Variable is not an anti-pattern of ReactJS/ReactNative. Since the value does not require UI to re-render, hence storing in Class Variable is not an issue.
Appreciate anyone to comment further. Thanks.
If this variable is something that will never change and doesn't depend on anything that exists in the scope of your component, I'd suggest storing it as a constant outside of your component instead.
If you do need to generate it based on things that are in the scope of your component, you need to store it either as a state or as a class variable.
I would recommend that you store it as a state only if you need to update your UI when that variable changes (with setState). If you don't need that, it's better to store as a class variable. And the reason is that if you store it on a state, without actually requiring a UI update when that variable changes, you will end up causing unnecessary re-renders, that may be expensive.
Also, storing something that is by definition not a state, inside a state, is more confusing in my opinion than storing it separately as a class variable.
Btw, If you're working in a project that allows you to move from class components to hooks, I'd strongly suggest so.
I have built my own FormBuilder component (which is almost 5k line now), so it can cover all my needs, one issue i'm encountering is loading a new set of FormData any time the user needs, since my FormBuilder can accept a set of nested components, its kinda hard comparing the changes, and handling everything in component did mount, one easy way is building a loadFormData method inside the FormBuilder and calling this method from outside the component
I know this can easily be accomplished using ref attribute, but react highly suggest avoiding this and i got discouraged! and i was not sure if i should do this or not!
So i came up with a new alternative which kinda does the same thing:
class A {
onGetFormBuilderInternalFunction = (functions) => {
this.formBuilderFunctions = functions
}
onLoadButtonClick = () => {
this.formBuilderFunctions.loadFormData(someNewData)
}
render () {
<FormBuilder onGetInternalFunction={this.onGetFormBuilderInternalFunction}
}
}
class FormBuilder {
componentDidMount() {
if (this.props.onGetInternalFunction) {
this.props.onGetInternalFunction({
loadFormData: this.loadFormData,
})
}
}
}
So what do you think ?, is this a better approach ? or is this still a bad one ?, i was thinking using this method will at least only gives access to functions i need and not everything else.
I should also mention, loadFormData is simply one example, and there are at least a couple of these special function which i really really think is best to simply call from outside, so even if i do somehow pass the new data from props and handle it in componentDidUpdate, for the rest of these functions, i still need to access the FormBuilder
Yes that is the correct way to do it. However, if you have a 5,000 line component I would strongly suggest breaking it up into smaller sub components.
Keep state and handler functions in Parent and pass it down to FormBuilder as props.
I'm not sure how your component is set up so these are just thoughts based on a vague understanding.
Generally, you wouldn't want to do either of those approaches. Instead, the recommended approach is to pass someNewData to FormBuilder as one or more props (I'm guessing one prop, in your case).
Avoid using refs for anything that can be done declaratively.
– React Docs: When to Use Refs
This sort of scenario is discussed in Lifting State Up:
Instead of trying to sync the state between different components, you should rely on the top-down data flow.
– React Docs: Lifting State Up # Lessons Learned
If you're keeping track of changed state separate from your initial data, then you just need to reset that state when the form data (someNewData) changes. However, that's not the recommended approach.
Instead, uncontrolled components might be a great fit. By setting defaultValue to the initial data (i.e. someNewData.someField) and then letting the component deal with the value until you need it (e.g. when submit is clicked read the value from the component), you might be able to simplify your FormBuilder. Note: if you want to reset the uncontrolled component when your initial data (someNewData.someField) changes, you will need to use a key prop on the uncontrolled component with the value based someNewData.someField.
If you want to “reset” some state when a prop changes, consider either making a component fully controlled or fully uncontrolled with a key instead.
– React Docs: React Component # static getDerivedStateFromProps()
In response to your main question:
Better as you are doing right now than using ref.
I base this answer on what the react documentation says in the last paragraph of the "ref" glossary description and that the current approach can also be supported in case FormBuilder is refactored to be a functional component in the future (with Hooks and so), while using "ref" wouldn't.
I Am new to angular2. Trying to understand the usage of #Input in a better way. We can pass values from parent component to child using #Input also we can create a service variable and inject it to the parent component and can access them in child components. Which way would be better? I am getting these values through route resolves. I am feeling skeptical to use #Input when there is no binding of it with user input.
Generally there are two types of components - Presentational and Container or also sometimes called stateful and stateless. Here is the expert from this article explaining the difference:
Presentational components:
Are concerned with how things look.
Receive data and callbacks exclusively via props.
Rarely have their own state (when they do, it’s UI state rather than data).
Container components:
Are concerned with how things work.
Provide the data and behavior to presentational or other container components.
Are often stateful, as they tend to serve as data sources.
Presentational components should receive as much data as possible in a declarative way through input bindings. Container components should use DI as much as possible.
I'm just guessing but like anything it depends on the use case.
If your child component is acting like a stateless component but depends on the data the parent container has state-like access then you'd probable want to use input to pass down the data to the child components.
For example one case that comes to mind is the use of form groups and formcontrols
which the container keeps track of sort of the formgroup logic/state and on submit if the form is reactive will send a data object back or least should.
I'm not familiar myself but the use case for input that makes sense is when you have just rendering visual components that need just some data referenced from the parent container.
hope that makes sense. :) or least shed light on one use case hehe
http://learnangular2.com/inputs/
"most developers need to know how to pass data into components to dynamically configure them."
another good pictoral guide: https://www.sitepoint.com/angular-2-components-inputs-outputs/
Well, to be precise #Input() has nothing to do with user input as you think. It is basically used for passing data from parent component to child component. I agree that the name Input() leads to confusion, but its usage is different. Coming to service injection, this is not related to parent-child. Components at any hierarchy can inject services independently as they need. To conclude it, best method to pass data from parent to child is using #Input().
I am trying to create a form using reactjs , I am trying out twoway binding .
I am not able to use props in the valueLink because it is can only take state .
Problem 1 : I am passing in properties when creating a component and in getInitial state I am setting it into state , as I cannot use props in valueLink . What is the better approach ?
I want to send every change in a text box to do some computation in server and get the computed values to state.
Problem 2 : I am unable to use method componentWillReceiveProps because , I use state .I am also unable use shouldComponentUpdate as I cannot do setState. What can I use here ?
valueLink doesn't work on props. You might want to try React without the two-way binding helper. The helper is really there as a convenient sugar, not as a full library feature (since React doesn't need two-way binding).
For problem 1: this is an antipattern, and another reason why you should try React without the binding helper first. Let a prop stay a prop (in most cases).
For problem 2: that is also something that's made harder by your decision of using the binding helper. As for "unable to use shouldComponentUpdate", I'm not sure what you mean.
It seems that the value of your input is controlled higher in the hierarchy and passed down as prop. Here's what you would do without add-on: http://jsfiddle.net/TcfWe/
Note that I put the doSomeComputationOnServerSide in the parent because it feels more coherent to be alongside value's source of truth. Depending on your needs, you might put it in the child.
I am writing a complex react app and using Cortex as my central model. The philosophy with cortex is that it wraps your data and on changing the data, calls a complete re-render from the root. This works great especially when you have non hierarchical views changing state and affecting the other.
The issue that I am facing is maintaining states/props on re-render. For example I have a certain hierarchy which goes like this:
<Page>
<EditorCard>
<Editor/>
<PublishButton/>
</EditorCard>
</Page>
The EditorCard needs the JavaScript instance of the Editor in order to make changes to the Editor on clicking the PublishButton (I am using an external library inside Editor which exposes methods for editing). Hence the Editor on ComponentDidMount sets the instance as a prop on the EditorCard by calling a function passed down to it.
My issue is that when I click the PublishButton I change the value of the cortex object which causes a re-render from the root and I loose the props for that Editor (since component is already mounted ComponentDidMount is not called again).
The way I took care of this problem is by caching of getDefaultProps.
Inside EditorCard my default props are:
getDefaultProps: function() {
return {
cachedData: {},
}
},
And is saving the editor instance as this.props.cachedData.editor = editorInstance
This saves props over multiple re-renders.
Is this how getDefaultProps caching was meant to be used? On saving props over multiple re-renders am I breaking some of the core react rules with this hack? Could you suggest a better structure if so?
No, getDefaultProps is what it means to be: getting the default props in case the owner hasn't passed those to you. You could say it's a shorthand for a = this.props.bla || 'hello';.
That being said, if I'm understand your question correctly, I see three ways to solve it.
Cache that in your state instead. Props are passed by the parent and are meant to be read from, inside the child, at least in vanilla React.
Instead of putting that props passing logic in your componentDidMount, why not put it in componentDidUpdate?
ref lets you grab the instance and call its methods directly.