Can't use state value as props for child component - javascript

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.

Related

React.js/Redux - How to update state if props wasn't changed?

I want to update my local state if the props were changed. But I could not find a suitable solution to this problem. getDerivedStateFromProps gives me only nextProps and prevState but I need both prevProps and nextProps. Please write any your solution that might solve this problem)
Situation: The Cart component (stateful) gets the fetched data from the props and puts that data in this.state.cart. The Cart component has counterHandler method that triggers whenever the counter is changed (onIcrease, onDecrease, onChange). This handler calculates the data and makes a new data based on the event ( calculating totalPrice and updating the amount of the item ). Then puts the new data into setState to update the UI. The state doesn't change because I do this:
static getDerivedStateFromProps(nextProps, prevState) {
if (!_.isEqual(nextProps.cart, prevState.cart)) {
return { cart: nextProps.cart };
} else return null;
}
I do this because I want to update the state when the real data is changed ( the data that comes from the props ).
Goal: updating the counter's and the total price's value without making any-side effect ( the values might be updated in the store or only for the local state ).
This is what I mean:
You might want to use componentDidUpdate which is called when the props on the component update. It receives prevProps and prevState as parameters, and you have access to "nextProps" as this.props.
For example
componentDidUpdate(prevProps, prevState) {
if (!_.isEqual(this.props.cart, prevState.cart)) {
this.setState ({ cart: this.props.cart });
}
}
You can use componentWillReceiveProps method of react class. This method will be executed when parent component will render, its child will execute componentWillReceiveProps method in child. In this method in child you can update state based on new props.
componentWillReceiveProps(nextProps){
//You can access current props via this.props
//You can access newProps from argument
//Change component state after comparing both props
}

Is the react state meant to be used within the component it is defined?

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.

React pass Array from Parent state to child state

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!

One-Way Data Flow: Child component doesn't update when prop is asynchronously updated by parent

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 reason about. In addition, every
time the parent component is updated, all props in the child component
will be refreshed with the latest value. - One-Way Data Flow
The Vue2 Component Docs suggests doing the following to use props as an initial value:
// via https://v2.vuejs.org/v2/guide/components.html#One-Way-Data-Flow
props: ['initialCounter'],
data: function () {
return { counter: this.initialCounter }
}
So in my code I mimicked those instructions here.
However data() in Note.vue isn't being updated even though the prop value is received according to vue-devtools.
Haven't had success setting the values with the mounted or created lifescyle methods.
When I use static data, this seems to work fine, how can I ensure the child component reacts to receiving props when it comes from a remote source?
When you are passing initialNote as prop for initial value, but I see initialNote is being populated asynchronously in getNote method, so it will not be present initially when the component will be mounted. It will be populated after some time by the time initialisation would have already happened.
In the example give in vue documentation, initialCounter is static value which will perfect as it will have same value from beginning.

Does React rerenders component when a prop is changed

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

Categories