Do not mutate the state directly, that's what the doc said.
I was coding a todo list and make the same mistake of mutating the state directly, but in my case I was using hooks. I didn't understand why the screen does not re-render when I run setState. The state did mutate (confirmed by console.log
) and even useEffect
ran because it detects an updated dependency.
React class that extends Purecomponent has the same behaviour too.The funny thing is, if I were to use class that extends React.Component and use this.setState function the app does rerender the screen.
After I ask and learn, it turns out I need to treat states as immutable.
This code :
var newwrongArr = this.state.arr;
Does not copy anything, it only refers the value, the proof is that if you mutate newwrongArr
the state will also mutate.
If we want to copy, the code should be :
var newArr = [...this.state.arr]; //the three dots are spread operator
or some other function like Object.assign().
My conclusion is, if we mutate newwrongArr
and setStatearr(newwrongArr)
, I think React hooks will decide that rerender is unnecessary because it consider newwrongArr
to be the same as the value of state (although the state changes, the rerender does not happen). But if we were to copy the value with spread operator, then setState will consider rerender necessary which is the expected result.
Sorry for the long answer.