Following comes from React tutorial:
const squares = this.state.squares.slice();
squares[i] = 'X';
this.setState({squares: squares});
This code changes copied state.squares
and assign it to orginal state.squares
. Finally this changes original state.squares
, so I think this is not different than mutable code like following:
this.state.squares[i] = 'X';
Is there some difference?
Never mutate this. state directly, as calling setState() afterwards may replace the mutation you made. Treat this. state as if it were immutable.
Why Immer works well for React State Immutability? In React, using an Immutable state enables quick and cheap comparison of the state tree before and after a change. As a result, each component decides whether to re-rendered or not before performing any costly DOM operations.
Properties in React are immutable, read-only objects used to pass down data from a parent to its child component. Props facilitate the transfer of a piece of state or functionality you wish to make accessible to a sub component down the hierarchy. Syntactically, props resemble the way attributes are written in HTML.
Instead, we should use setState() . One reason is, for a pure component, directly mutating state won't trigger the component re-render, which could cause some odd bugs. With setState() we can change the state without directly mutating it.
React state should be treated as immutable. Never mutate this.state directly, as calling setState () afterwards may replace the mutation you made. Treat this.state as if it were immutable. Why? setState batches work behind the scenes. This means a manual state mutation may be overridden when setState is processed.
This applies to React in many places. For example, you should never mutate the state property of a component directly, but only through the setState () method. In Redux, you never mutate the state directly, but only through reducers, which are functions.
This method is really useful when we are setting a value in the state in such a way that it depends on its previous value. For example, toggling a boolean (true/false) or incrementing/decrementing a number. Click me! How to update an object with setState in ReactJS?
second reason, state changing is asynchronous in React, so you might have some other components changing state behind the scene while you are still referring to the old unchanged state, which result in wrong state values Show activity on this post. This code is immutable, because slice () method is used.
I do wonder about this question too. But I find that the answers were unsatisfactory. So here is my take
The answer is actually written in the doc itself http://reactjs.org/docs/state-and-lifecycle.html#do-not-modify-state-directly
so first reason, setState()
triggers render()
second reason, state changing is asynchronous in React, so you might have some other components changing state behind the scene while you are still referring to the old unchanged state, which result in wrong state values
This code is immutable, because slice()
method is used. If you try:
someState = {squares: [1,2,3,4,5]}
squares = someState.squares.slice()
You'll get new array created by slice()
method.
You can test it that way:
squares = someState.squares.slice()
squares2 = someState.squares
squares[0] = 9 // doesn't change someState
squares2[1] = 9 // changes someState
someState.squares // [1,9,3,4,5] - as I said
And if you have doubts about this.setState({squares: squares});
- yes, of course after running this you have new state, but in fact this state is not modified old state object, but new object created from old parts. So if you try:
oldState = this.state
this.setState({squares: squares})
You'll see that new state will differ than saved old:
this.state == oldState //false
In case of this.state.squares[i] = 'X';
oldState
would be modified too and that is exactly what we call mutability. All copied parts of old state changes with it and that causes many problems.
You can do this, but you should not, the reason behind is that, if you use
this.state.squares[i] = 'X';
It will be overridden with next
this.setState({squares: squares});
So, your app will not have accurate data.
From Doc:
Never mutate this.state directly, as calling
setState()
afterwards may replace the mutation you made. Treat this.state as if it were immutable.
Check more about this in https://facebook.github.io/react/docs/react-component.html#state
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With