Heads up! To view this whole video, sign in with your Courses account or enroll in your free 7-day trial. Sign In Enroll
Preview
Start a free Courses trial
to watch this video
Whenever you need to update state based on previous state, you shouldn't rely on this.state
to calculate the next state. State updates may be asynchronous, so it may not always lead to the component re-rendering with new data, and could cause state inconsistency. setState()
accepts a callback function that produces state based on the previous state in a more reliable way.
Our counter score is updating correctly.
0:00
However, we're still mutating or
altering state directly.
0:03
Notice how we're updating the component
score state by directly accessing
0:07
this.state.score.
0:11
The way setState works is it takes
the object past to it with the updated
0:13
state and eventually merges it into
the component's current state.
0:18
According to the React docs,
a state update may be asynchronous.
0:23
In other words,
0:26
sometimes updates to the DOM don't happen
immediately when you call this.setState.
0:27
If you have multiple setState
calls inside of an event handler,
0:33
React will often batch, or bundle
the updates together into a single update.
0:36
This is done for
0:40
performance reasons, so that your
UI is rerendered more efficiently.
0:41
So because state maybe updated
asynchronously, whenever you need to
0:45
update state based on previous state,
like update a score based on the previous
0:50
score, you shouldn't rely on this
.state to calculate the next state.
0:55
While it's technically possible
to change state this way,
1:00
as you can see our counter
is working just fine.
1:04
It may not always lead to the component
rerendering with the new data and
1:07
could cause state inconsistency.
1:11
So instead of an object,
setState also accepts a call back function
1:13
that produces state based on the previous
state in a more reliable way.
1:18
So let's first modify the setState
method in increment score
1:22
to take a call back function.
1:26
The call back function receives the
previous state as its first argument and
1:27
the props at the time the update is
applied as an optional second argument.
1:32
We are only going to check the previous
value of state before setting a new value,
1:36
so let's pass the call back or
1:41
reference to the previous state
with the parameter prevState.
1:43
We will add the arrow then wrap
the score property in a return
1:48
statement with curly braces.
1:52
Now we'll replace this.state.score
with prevState.score.
2:01
And we'll do the same with
the decrement function.
2:10
Our counter still functions the same way,
but
2:33
now we have a more reliable way to
set state based on previous state.
2:36
Because the callback function is
guaranteed to fire after the update is
2:40
applied and rendered out to the DOM.
2:45
And to make the callback more concise,
you could omit the return keyword and
2:49
curly braces, by wrapping the body
of the function in parentheses.
2:53
So whenever you're updating to a new
state based on a previous state,
3:15
it's actively recommended
that you use this approach.
3:20
That way, you can be sure that
state did indeed update correctly.
3:24
You need to sign up for Treehouse in order to download course files.
Sign up