Suppose I have two components named Parent and Child. In Parent component I have a state named lastName which is passed to Child as a prop. Now after initial rendering of Child and Parent, if the lastName in Parent changed, will it cause Child component to rerender?
Yes, if you set the property via setState. However, re-render in React isn't something you should be afraid of, it's very efficient due to Virtual DOM usage.
In the child component you should use the following
shouldComponentUpdate(nextProps){
return this.props.lastname !== nextProps.lastname
}
https://facebook.github.io/react/docs/component-specs.html#shouldComponentUpdate
After that, in the child component you might need to update the state. To achieve that you can use componentWillReceiveProps(nextProps)
componentWillReceiveProps(nextProps){
this.setState({
lastname: nextProps.lastname
});
}
The Child component is only re-rendered when props lastName is being used in Child's render function and Parent use setState function to change lastName. Remember, React is one-way dataflow, if you want to re-render Child component right inside the Child, you must call an event which also trigger setState back to Parent component
Related
I am Working on a ReactJs project and I use formik in it.
I have 2 different components (parent and child).
Here is the example, I tried to pass the formik data from parent to child and I need to set parent formik values from child component.
Right now I face an error as my parent component call child and when the child updates parent value it will again call the child and goes in the infinite loop.
Parent.js
<GSTData gstData={this.props.gstDetails?.GstDetails}
amount={this.props.totalAmount}
onInputControlChange={(Total, GstData) => {
TotalBillAmount = Total;
GstDetails = GstData;
console.log('Total', TotalBillAmount)
//setFieldValue('NetOutStanding', 1);
}}
values={values}
setFieldValue={setFieldValue}
/>
Child.js
componentDidUpdate(){
this.props.onInputControlChange((this.GSTTotal + this.props.amount), this.GstDetails);
this.props.setFieldValue('NetOutStanding', (this.GSTTotal + this.props.amount));
}
What's happening is that when you update the input it calls the parent with the value to set. The parent then passes that value back to the child as a prop, which the Child perceives as an update, which then tells the parent the value again..... thus infinite loop
I would try taking
this.props.setFieldValue('NetOutStanding', (this.GSTTotal + this.props.amount));
out of the componentDidUpdate in the child component and calling it from it's own function.(This means you'll also have to set the value of the input being passed in from the parent directly). That should break the cycle
Should react component state is meant to be used in the component in which it is defined?
I faced a scenario, where a component state is updated by two different components and is passed as a prop to its child. But never used in the component where it is defined.
For example: I have a component CommonComponent which has a state, 'stateObj' and it has two child components ChildComponent and ModifyComponent.
I have one more component, CreateComponent which is a parent of CommonComponent.
I have two cases here:
During create action, CommonComponent receives props from CreateComponent and updates the state- 'stateObj' and is passed as a prop to ChildComponent
During modify action, ModifyComponent updates the state of CommonComponent using a callback and in turn the 'stateObj'
is passed as a prop to ChildComponent
Is this a valid way of using the component's state? As I understood, The state is meant to be used by its component in which it is defined. But, here I am not using the 'stateObj' in CommonComponent. but, i am just using it to send data to its child components. Am I using the state in a right way? or is there any other way of doing this?
your suggestions are really precious!
Thanks in advance.
You could move the state to CreateComponent instead of having it in CommonComponent. So, ModifyComponent and CommonComponent will have callback props which will update the state in CreateComponent.
I have a parent component holding a state called nodes which is established as an array. I am trying to pass this.state.nodes to a child component and have that component have the array as part of the child component state, but it's not working. Here is the code:
<ChildComponent nodes={this.state.graphNodes}/>
This is in the return statement. After some testing/console logging I know the prop is being passed.
In the child component, I have:
this.state = {
nodes: this.props.nodes,
links: [],
totalNodes: [],
totalLinks: []
}
But when I try to reference it or map it or do anything with it in the child component render or return it's telling me it's an empty array.
Since graphNodes is in a component state, i think its initial value should be an empty array, and you are initializing state with props.nodes at constructor, since constructor renders only once at initialization stage of the component at that moment graphNodes must be an empty array, after you change the parent component state, the state in the child component will not update. That makes graphNodes state always an empty array.
Why don't you use props directly, if you don't have to change the graphNodes values in the child component you can use it directly from props.
If you really want map props to state, you have to do it in componentDidUpdate lifecycle method with proper conditions
All of the comments were dead on. Using this.props.nodes directly instead of trying to put it in child state was the perfect solution. Thanks to all who replied!
In VueJS, I have seen different ways of accessing parent properties from a component. Say I want to use the parent property items in my component.
First way
The component has a props value bound to a parent property:
.js
Vue.component("example", {
template: "<div></div>",
props: ["myItems"]
});
.html
<example v-bind:my-items="items"></example>
Second Way
The child component accesses a parent's properties directly, like this:
this.$parent.items
Question
Is there a reason to use the more elaborate first method over the second? Is there an overhead to "duplicating" data like that, vs. accessing it directly when needed?
The props should be mutated in the parent component, according to the official doc :
All props form a one-way-down binding between the child property and the parent one: when the parent property updates, it will flow down to the child, but not the other way around. This prevents child components from accidentally mutating the parent’s state, which can make your app’s data flow harder to understand.
In addition, every time the parent component is updated, all props in the child component will be refreshed with the latest value. This means you should not attempt to mutate a prop inside a child component. If you do, Vue will warn you in the console
So in order to update props from child component you should use this.$emit event and send the new value in order to handle the update in the parent one.
In my react js app, I can't seem to use the state value as props for the child component.
In the parent component, constructor, the app has a null state called selectedWarehouseID.
This state(selectedWarehouseID) should update with some information in the componentWillMount() method.
Now, in the render method of the parent component I am embedding another child component that has this state as a props.
<ItemChooser
productsByWarehouse = { this.state.selectedWarehouseID }
/>
Now here's the problem, in the child component, the value of this.props.productsByWarehouse is always null. I found a nice explanation of why this happens, but how to wait for the data that updates in the parents componentWillMount() to access the updated value of the state that being passed in the child component props?
Possible solutions are:
1. You are storing the props value in state of child component so, Update the state of child component whenever any change happen to props values (state of parent). For that use componentWillReceiveProps lifecycle method.
componentWillReceiveProps():
is invoked before a mounted component receives new props. If you need
to update the state in response to prop changes (for example, to reset
it), you may compare this.props and nextProps and perform state
transitions using this.setState() in this method.
Like this:
componentWillReceiveProps(newProps){
this.setState({
value: newProps.productsByWarehouse
});
}
Note: Replace value by the actual key in which you are storing the value.
2. Don't store the props values in state of child component, directly use this.props.productsByWarehouse, Whenever you change the parent state values, child will automatically get the updated value in props.