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
}));
Top comments (3)
** 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.
Hi Sung,
Thanks for your reply!
Perhaps my question wasn't clear enough, sorry for that. I posted the two options (from the React docs) knowing that those were the correct ways to implement state, BUT my question is when to use one over the other. Why are there two correct ways when Option 2, IMO, should always be used. Why have Option 1, when there's Option 2? Hope that clears it up.
Yikes.. I am sorry I misunderstood the question 😰
How I understood was that they are basically the same providing devs multiple ways to do the same thing depending on your need.
So if you don't need to use previous state or props, then go with option 1 else option 2.
Unrelated to the main question,
For memoization in React Hooks, they have two different ways to memoize (useCallback & useMemo, which do the same thing but
useCallback
is called like Option 1 ofsetState
, whileuseMemo
is called like Option 2 ofsetState
).Official doc shows that
But I don't know enough history about React why there is only
setState
but two for memoization 😅