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?
Create a copy of the state:
let someProperty = JSON.parse(JSON.stringify(this.state.someProperty))
make changes in this object:
someProperty.flag = "false"
now update the state
this.setState({someProperty})
We use Immer https://github.com/mweststrate/immer to handle these kinds of issues.
Just replaced this code in one of our components
With this
With immer you handle your state as a "normal object". The magic happens behind the scene with proxy objects.
To make things generic, I worked on @ShubhamKhatri's and @Qwerty's answers.
state object
input controls
updateState method
setState as @ShubhamKhatri's answer
setState as @Qwerty's answer
Note: These above methods won't work for arrays
Sometimes direct answers are not the best ones :)
Short version:
this code
should be simplified as something like
Long version:
Currently you shouldn't want to work with nested state in React. Because React is not oriented to work with nested states and all solutions proposed here look as hacks. They don't use the framework but fight with it. They suggest to write not so clear code for doubtful purpose of grouping some properties. So they are very interesting as an answer to the challenge but practically useless.
Lets imagine the following state:
What will happen if you change just a value of
child1
? React will not re-render the view because it uses shallow comparison and it will find thatparent
property didn't change. BTW mutating the state object directly is considered to be a bad practice in general.So you need to re-create the whole
parent
object. But in this case we will meet another problem. React will think that all children have changed their values and will re-render all of them. Of course it is not good for performance.It is still possible to solve that problem by writing some complicated logic in
shouldComponentUpdate()
but I would prefer to stop here and use simple solution from the short version.Something like this might suffice,
I used this solution.
If you have a nested state like this:
you can declare the handleChange function that copy current status and re-assigns it with changed values
here the html with the event listener