I'm still new with React and am trying to understand when we would use each of the, according to React team, correct ways of setting state. I've seen both methods used, but confused when one way would be used over the other.
Why wouldn't we always use Option 2 below?
Here is the link to the React Docs on this section
Do Not Modify State Directly (Option 1)
this.setState({comment: 'Hello'});
State Updates May Be Asynchronous (Option 2)
this.setState((state, props) => ({
counter: state.counter + props.increment
}));
** update **
Woops, 😅 I didn't catch that
#explainlikeim5
tag...Hi Brian,
Those two examples are actually recommended ways.
From what I read from docs, following examples are the
wrong
ways.Do Not Modify State Directly
👆 is wrong because (short answer is that) React would not know whether
this.state.comment
is updated withoutthis.setState(...)
.Longer answer is due to React tracks state changes (Reconciliation).
A state is an object, thus a reference type. Checking whether each state in each object for all components in React tree would be prohibitively slow. So when you are doing
this.setState({comment: 'Hello'})
, you are basically setting a new reference forthis.state
and alerting React to queue the changes for render later.When you do
this.state.comment = "Hello"
, you didn't change the reference ofthis.state
but only the value pointed by the reference thus React would not know that the state has changed.State Updates May Be Asynchronous
For this case, while you are changing
counter
state withinthis.setState
, eitherthis.state.counter
&this.props.increment
could have a difference value from the time you tried to set the counter value.Suppose that in your code
As
setState
is asynchronous, when React is trying to apply thesetState
, values forthis.state.counter
or/andthis.props.increment
(such as 2, 3, etc) could have changed by external event/side effects (e.g. setInterval, mouse, keyboard events, etc).When you use the "correct" callback version,
React knows what the previous
state
&props
were and gives you the snapshot of those values, thus no need to worry about it being changed elsewhere.I could be missing something or wrong somewhere.
If so, would anyone kindly point out my mistakes? 🙂 Thanks.