I'm trying to organize my state by using nested property like this:
this.state = {
someProperty: {
flag:true
}
}
But updating state like this,
this.setState({ someProperty.flag: false });
doesn't work. How can this be done correctly?
Here's a variation on the first answer given in this thread which doesn't require any extra packages, libraries or special functions.
In order to set the state of a specific nested field, you have set the whole object. I did this by creating a variable,
newState
and spreading the contents of the current state into it first using the ES2015 spread operator. Then, I replaced the value ofthis.state.flag
with the new value (since I setflag: value
after I spread the current state into the object, theflag
field in the current state is overridden). Then, I simply set the state ofsomeProperty
to mynewState
object.You can also go this way (which feels more readable to me):
In order to
setState
for a nested object you can follow the below approach as I think setState doesn't handle nested updates.The idea is to create a dummy object perform operations on it and then replace the component's state with the updated object
Now, the spread operator creates only one level nested copy of the object. If your state is highly nested like:
You could setState using spread operator at each level like
However the above syntax get every ugly as the state becomes more and more nested and hence I recommend you to use
immutability-helper
package to update the state.See this answer on how to update state with
immutability helper
.To write it in one line
I take very seriously the concerns already voiced around creating a complete copy of your component state. That being said, if compromised performance is not of paramount concern (i.e. you don't have a very deep tree of components which React would want to re-render) I would suggest Immer.
This should work for
React.PureComponent
(i.e. shallow state comparisons by React) asImmer
cleverly uses a proxy object to efficiently copy an arbitrarily deep state tree. Immer is also more typesafe compared to libraries like Immutability Helper, and is ideal for Javascript and Typescript users alike.Typescript utility function
If you are using ES2015 you have access to the Object.assign. You can use it as follows to update a nested object.
You merge the updated properties with the existing and use the returned object to update the state.
Edit: Added an empty object as target to the assign function to make sure the state isn't mutated directly as carkod pointed out.