Loading video player...
In the previous lesson, we saw something
strange. We logged count before and
after calling set count, and both logs
showed zero, but the UI showed one. This
is something that trips up almost every
React developer when they're starting
out. So, let me explain why it happens.
It comes down to the three phases we
talked about in the previous lesson.
Trigger, render, and commit. When the
increment button is clicked, we enter
the handle click function. And the
moment we call set count, we officially
enter the trigger phase. At that point
React simply marks the component for a
rerender. It doesn't stop your function
halfway, rerender the component, and
then jump back into your function. That
never happens. Instead, React lets your
entire event handler run from start to
finish using the current state. And only
after the handler completes does React
move on to the render phase and call
your component again with the new value.
Let me update the logs to make this
really clear. Back in our simple counter
component, I'm going to update this to
render phase component rendering with
count is equal to count. And within
handle click I will update the last
console lock statement still in trigger
phase after set count. Count count is
count. Go back to the browser. And we
have an error because we have log
statement before state initialization.
Save the file. Refresh. Clear the
console. And now watch the log
statements when I click the button
increment. Before set count, count count
is zero. Still in trigger phase. After
set count, count count is zero. Render
phase component rendering with count is
equal to one. You can see that the
render phase happens after your event
handler finishes. During your event
handler, you're still in the trigger
phase and working with a snapshot of
state from the current render. And this
is the key takeaway for this lesson. In
React, state updates are not immediate.
When you call set state, you're
scheduling an update for the next
render. Inside your current render, the
state values won't change. There is
snapshot and snapshots don't change. So
if you log the count inside your event
handler, you will always get the same
value. Think of it like taking a photo.
Once you take the photo, the people in
it don't move, even if the real people
walk away. State in a render is like
that photo. it's frozen at that moment
in time. Keep this in mind because it
becomes really important when you try to
do multiple updates in a row and expect
React to keep up. Let me show you an
example of what I mean. In our simple
counter component, I'm going to update
the handle click function to add two
more set count calls in a row with logs
to show the count. So call count passing
in count + one and add a lock statement
after set count + one count is count.
I'm going to duplicate these two
statements. So we have multiple set
count calls. I'm going to update the
second one to count + 5. After set count
+ 5 and the third one set count + 10.
Let's save the file. Go back to the
browser and let's see what happens when
I click the button refresh. Clear the
console. Click increment. After set
count, count + 1, count is zero. After
set count, count count + 5, it's still
zero. After set count, count + 10, still
zero. Why does that happen? Because
throughout the trigger phase, which is
our entire event handler, our snapshot
of state is zero and we are only queuing
updates. So set count 0 + 1 will cue an
update to 1. Count 0 + 5 will cue an
update to five. Count 0 + 10 will cue an
update to 10. The last update wins. And
only when the render phase happens does
count actually become 10, which we can
see in the console render phase
component rendering with count is equal
to 10. Even if you were to add a set
timeout, the count would still be zero
because the state is still a snapshot
and frozen in time. So within handle
click, let's add set timeout. We pass in
a callback function that is going to run
after 2 seconds and we will log to the
console after 2 seconds. Count is count.
Back in the browser, refresh the
console. Click increment. We see the
three zeros. And after 2 seconds, the
count is still zero. The trigger
render, and commit phases all complete.
And the UI shows 10, but the set timeout
log message still shows zero. Variables
value never changes within a render
even if its event handlers code is
asynchronous.
This snapshot behavior might seem weird
at first, but it's actually what makes
React predictable. Your event handlers
work with consistent data and you don't
have to worry about values changing in
the middle of your function. I hope this
makes sense because it is really
important to understand. Now, we do have
a few more things to cover about state.
So, let's keep going.
Github - https://github.com/gopinav/React-19-Tutorials Become a Fullstack Developer with Scrimba - https://scrimba.com/fullstack-path-c0fullstack?via=Codevolution Follow me + Twitter - https://twitter.com/CodevolutionWeb Business - codevolution.business@gmail.com State as a Snapshot in React 19