State Update Batching in Practice | Lecture 133 | React.JS 🔥

The Coding Classroom
5 Dec 202315:44

Summary

TLDRThis video script delves into the intricacies of state updates in React, demonstrating how React batches state updates asynchronously for improved performance. Through practical examples and code snippets, it explores the behavior of state updates within event handlers, setTimeout functions, and the changes introduced in React 18 for automatic batching across different scenarios. The script provides a comprehensive understanding of when and how to use callback functions for setting state based on the previous state, ensuring safe and predictable updates. With a hands-on approach, it effectively showcases the power of React's state management and batching mechanisms.

Takeaways

  • 😄 React batches multiple state updates into a single re-render to improve performance.
  • 🤔 Using console.log('render') can demonstrate when components re-render due to state changes.
  • ⏱️ State updates in React are asynchronous, so accessing the updated state immediately after setState() will return the previous state value.
  • ✅ When updating state based on the previous state, always use the callback function form of setState() to ensure the correct state is accessed.
  • 🔄 React will not re-render a component if the new state is identical to the current state.
  • ⚡ In React 18, state updates are automatically batched, even for asynchronous operations like setTimeout() and promises.
  • 👴 In React 17 and earlier versions, state updates in asynchronous operations were not batched automatically.
  • 🔑 Understanding batched updates and the asynchronous nature of setState() is crucial for writing efficient and bug-free React applications.
  • 📝 The provided script demonstrates several examples and scenarios to illustrate these concepts in action.
  • 🚀 Mastering state management and updates is a fundamental skill for becoming a proficient React developer.

Q & A

  • What is the purpose of the `handleUndo` function?

    -The `handleUndo` function is implemented to reset the `showDetails` state to `true` and the `likes` state to `0`. It is used to undo the changes made to these two states.

  • How does React batch state updates, and how can this be proven?

    -React batches multiple state updates together and only triggers a single re-render. This can be proven by logging a string to the console within the component's render method. If only one log appears after multiple state updates, it means the updates were batched and triggered a single re-render.

  • Why does the `console.log` statement with 'render' only appear once when clicking the 'undo' button?

    -The 'render' log appears only once because the two state updates (`setShowDetails` and `setLikes`) were batched together, causing a single re-render of the component.

  • Why is the state updating asynchronous in React?

    -State updating is asynchronous in React because the state is not updated immediately after calling the state setter function. Instead, the state is updated during the re-rendering process, which happens after the state setter function is called.

  • Why is it recommended to use a callback function when updating state based on the previous state?

    -Using a callback function when updating state based on the previous state ensures that the state update is performed with the latest state value. This safeguards against potential issues caused by stale state values, especially when the component's logic changes or when the state update function is called in different contexts.

  • Why does the component not re-render when clicking the 'undo' button after the state has already been reset?

    -The component does not re-render because both the `showDetails` and `likes` states were already at their default values (`true` and `0`, respectively). Since the new state values were equal to the current state, React did not trigger a re-render.

  • What is the purpose of the `handleTripleInc` function?

    -The `handleTripleInc` function is intended to increase the `likes` state by 3 when clicking the 'Next' button with three plus signs.

  • Why does the `likes` state only increase by 1 when calling `setLikes` three times in the `handleTripleInc` function?

    -The `likes` state only increases by 1 because the state updates are still asynchronous, and the subsequent state updates are based on the previous (stale) state value, not the updated value.

  • How does using a callback function in `setLikes` solve the issue of only increasing the `likes` state by 1?

    -Using a callback function in `setLikes` allows access to the latest state value within the callback. This ensures that each subsequent state update is based on the most recent state value, enabling the `likes` state to increase by 3 as intended.

  • What is the difference between automatic batching in React 17 and React 18 when using `setTimeout`?

    -In React 17, automatic batching did not occur inside a `setTimeout` function, resulting in multiple re-renders. However, in React 18, batching occurs automatically in `setTimeout` and other asynchronous situations, leading to a single re-render.

Outlines

00:00

🔄 Exploring State Batching and Asynchronous Updates in React

This paragraph discusses how React batches state updates and how state updating is asynchronous. It demonstrates this by implementing an 'undo' button that resets two states, and using console logs to observe the rendering process. It shows that state updates are batched, causing only one component re-render, and that accessing the state immediately after updating it yields the previous value due to the asynchronous nature of state updates.

05:01

⬆️ Implementing a 'Triple Increment' State Update Function

The paragraph focuses on implementing a 'triple increment' functionality that increases the 'likes' state by 3 when a button is clicked. It highlights the importance of using a callback function when updating state based on the current state value. The callback function ensures that the latest state value is accessed, allowing for correct updates. Without the callback, the state remains stale, leading to incorrect updates.

10:02

🔒 Ensuring Reliable State Updates with Callback Functions

This paragraph emphasizes the importance of always using callback functions when updating state based on the current state value. It demonstrates scenarios where directly updating the state or calling the update function multiple times can lead to unexpected results. Using a callback function safeguards against such issues and ensures reliable state updates, even when code changes or other developers interact with the functions.

15:05

🕰️ Automatic Batching in React 18 Outside Event Handlers

The paragraph explores how React 18 introduced automatic batching of state updates even outside event handlers, such as in setTimeout functions. It implements a button that resets the state after a 2-second delay, demonstrating that the state updates are batched and cause only a single re-render. Additionally, it compares this behavior with React 17, where automatic batching did not occur in setTimeout, causing multiple re-renders.

Mindmap

Keywords

💡State

State refers to the internal data of a React component. It represents the current condition or properties that determine how the component will render and behave. In the video, the instructor demonstrates how React manages and updates the state of components, particularly through state variables like `showDetails` and `likes`. Updating the state triggers a re-render of the component, allowing the user interface to reflect the new data.

💡Batching

Batching is a mechanism in React that groups multiple state updates together and performs them in a single re-render cycle. This optimization technique helps improve performance by reducing unnecessary re-renders. The video illustrates how React batches state updates within event handlers, ensuring that multiple setState calls within the same event handler result in only one re-render. The instructor also discusses how React 18 introduced automatic batching for updates outside event handlers, such as setTimeout callbacks.

💡Asynchronous State Updates

In React, state updates are asynchronous, meaning that the new state value is not immediately available after calling the setState function. The video emphasizes this concept by demonstrating that attempting to access the state immediately after updating it will still return the previous (stale) value. To update state based on the current state, the instructor recommends using a callback function passed to setState, which provides access to the latest state value.

💡Re-rendering

Re-rendering is the process of React updating the component's rendered output based on changes to its state or props. The video demonstrates how console logging 'render' can be used to visualize when a component re-renders in response to state updates. The instructor also highlights that React will skip re-rendering if the new state values are identical to the current state, optimizing performance by avoiding unnecessary updates.

💡Event Handlers

Event handlers are functions in React components that handle user interactions, such as clicks or form submissions. The video focuses on state updates within event handler functions, demonstrating how React automatically batches these updates for improved performance. The instructor implements event handlers like `handleUndo` and `handleTripleInc` to showcase how state updates are managed in response to user actions.

💡Callback Function

A callback function is a function passed as an argument to another function, which will be invoked later. In the context of the video, the instructor emphasizes the importance of using callback functions when updating state based on the previous state value. By passing a callback to the setState function, React provides the latest state value as an argument, allowing for safe and consistent state updates, even when the component's logic changes.

💡setTimeout

setTimeout is a built-in JavaScript function that executes a provided callback function after a specified delay in milliseconds. The video uses setTimeout to demonstrate how React 18 introduced automatic batching for state updates outside of event handlers. By scheduling a state update with setTimeout, the instructor shows that React now batches these updates, resulting in a single re-render, unlike in previous versions.

💡Stale State

Stale state refers to the situation where the state value being accessed or used is outdated or no longer represents the current state of the component. The video illustrates this concept by attempting to access the `likes` state immediately after updating it, resulting in the previous (stale) value being returned. This reinforces the asynchronous nature of state updates in React and the importance of using the correct techniques, such as callback functions, to access the latest state value.

💡Component Instance

A component instance in React refers to a specific instance or instantiation of a component class or function. Each time a component is rendered, it creates a new instance with its own state and lifecycle methods. The video discusses how React avoids re-rendering a component instance if the new state values are the same as the current state, as it would result in an unnecessary update.

💡Performance Optimization

Performance optimization is the process of improving the efficiency and responsiveness of an application or system. In the context of React, techniques like batching state updates and avoiding unnecessary re-renders are forms of performance optimization. The video emphasizes how these optimizations help React applications run smoothly and efficiently, particularly when dealing with frequent state updates or complex user interfaces.

Highlights

React batches state updates in practice, and state updating is asynchronous.

Implementing functionality to undo or reset states using a handleUndo function.

Using console.log to prove that state updates are batched and only cause one component re-render.

Demonstrating that state updating is asynchronous by accessing the state value immediately after updating it.

Explaining why the component is not re-rendered when the new state is equal to the current state.

Implementing a handleTripleInc function to increase the likes state by three.

Demonstrating that setState with a value updates the state asynchronously, causing stale state issues.

Using a callback function with setState to update the state based on the current state, solving the stale state issue.

Explaining the importance of using a callback function with setState to ensure correct state updates, even with future code changes.

Proving that automatic batching in React 18 works even outside of event handlers, such as with setTimeout.

Demonstrating the difference between React 17 and React 18 regarding automatic batching with setTimeout.

Summarizing the key points covered in the transcript, including state batching, asynchronous state updates, and the importance of using callback functions with setState.

Transcripts

play00:01

‫All right, so let's move back to our project,

play00:04

‫and see how React batches state updates in practice

play00:08

‫and how this state updating is in fact asynchronous.

play00:15

‫So let's come down here to our TabContent component,

play00:19

‫and then let's play around a little bit with the states

play00:22

‫that we have here.

play00:23

‫And first of all, I want to now implement the functionality

play00:27

‫of this undo button here.

play00:30

‫So this undo will basically undo

play00:32

‫or reset the two states that we have here.

play00:35

‫So this one, and this one.

play00:41

‫So let's write a simple function handleUndo.

play00:47

‫And then what it does is setShowDetails back to true,

play00:54

‫and set the likes back to zero.

play00:58

‫And then let's use that handler right here.

play01:05

‫So easy enough, handleUndo.

play01:09

‫And yeah, that works great.

play01:13

‫So as we just learned in the previous lecture,

play01:16

‫inside of this event handler function here,

play01:20

‫these two state updates are batched.

play01:23

‫So they will only cause one component re-render.

play01:27

‫Now how can we actually prove that?

play01:30

‫Well, one simple way is to lock something

play01:34

‫to the console here.

play01:37

‫So let's say render.

play01:39

‫And so then each time that the component gets re-rendered,

play01:42

‫and so then each time this console.log will log render

play01:47

‫to the console.

play01:49

‫So let's see.

play01:51

‫Let's first get rid of these other ones that we had here.

play01:57

‫So here there are, and okay.

play02:05

‫Now nevermind this one here that is a bit more grayed out.

play02:09

‫This is coming from somewhere else.

play02:11

‫So only this one render here is important.

play02:14

‫So this first render string here

play02:16

‫comes from the initial render of this TabContent component.

play02:20

‫And if we go to another tab, then we get another one,

play02:24

‫because of course, then this component here is updated.

play02:29

‫Now, okay.

play02:30

‫Now let's remove this, so that we start empty,

play02:34

‫or actually we will see a few more.

play02:37

‫So each time that we click here,

play02:38

‫the component function gets rendered,

play02:40

‫and so then the console.log is executed.

play02:44

‫And so this is actually a really nice way of proving

play02:46

‫that rendering is calling the component function.

play02:51

‫Now, all right?

play02:53

‫But now let's empty this.

play02:54

‫And then as I click this button here,

play02:56

‫we should only see one render here,

play02:59

‫which would then mean that these two state updates

play03:02

‫were batched.

play03:04

‫So let's see.

play03:05

‫And indeed, we only get one here.

play03:08

‫Great.

play03:10

‫Now let's also see that the state updating is asynchronous.

play03:16

‫So basically, if I try to access the number of likes here

play03:20

‫right after updating the state, then what happens?

play03:26

‫So first I need to of course increase a little bit,

play03:29

‫then let's clean this.

play03:31

‫And as I reset, well, we get five,

play03:35

‫which might be surprising.

play03:37

‫But if you paid good attention in the previous lecture,

play03:41

‫then this will actually no longer come as a surprise to you.

play03:46

‫So the reason that here we get five is that the state

play03:50

‫is in fact actually only updated after the re-rendering,

play03:55

‫or basically during the re-rendering,

play03:58

‫but not immediately after we call dysfunction.

play04:02

‫So that's impossible.

play04:03

‫And therefore, here we still get that old likes state,

play04:08

‫which again is still at five.

play04:11

‫Then now it is of course at zero,

play04:13

‫because now the re-rendering has already happened.

play04:17

‫Now, by the way, what do you think will happen,

play04:20

‫so what do you think will get rendered

play04:22

‫if we click the undo button again?

play04:25

‫So let's clear this.

play04:27

‫And so let's see what happens.

play04:29

‫So I click this now, and you see that no render

play04:35

‫was logged to the console.

play04:37

‫So why do you think that is?

play04:39

‫Why was the component instance not re-rendered this time?

play04:43

‫Well, it's because both of the state values

play04:47

‫were already at their default basically.

play04:50

‫So details was already true and likes was already zero.

play04:54

‫And so then as we attempted to update the state,

play04:58

‫both of them were actually not updated.

play05:01

‫And again, that's because the new state

play05:03

‫was equal to the current state.

play05:05

‫And so in that situation,

play05:07

‫React will not even try to attempt to update the state,

play05:11

‫and then of course, it will also not re-render

play05:14

‫the component instance.

play05:16

‫And so that's why, well, nothing happens.

play05:20

‫So as we keep clicking here, of course,

play05:22

‫the console.log keeps getting executed,

play05:25

‫but again, the component itself is not re-rendered.

play05:30

‫Okay, but let's move on here,

play05:32

‫and let's implement this next button here.

play05:36

‫So here I have these three pluses,

play05:38

‫which means that when I click here,

play05:40

‫I actually want like a super like,

play05:43

‫so this should then improve by three.

play05:47

‫So let's create a function for that.

play05:49

‫And I will just copy this one.

play05:52

‫And let's call it TripleInc.

play05:57

‫And then I'll just duplicate this here.

play06:00

‫And then let's come down here,

play06:04

‫onClick and then handleTripleInc.

play06:11

‫Okay, let's go back to our function,

play06:13

‫because this will become very important.

play06:17

‫So what do you think is going to happen

play06:20

‫when I click here now?

play06:22

‫Again, let's close.

play06:24

‫So what do you think will happen

play06:26

‫to the state here in particular?

play06:29

‫So let's see.

play06:31

‫And well, it only increased once,

play06:35

‫so not three times as we might expect.

play06:39

‫But were we actually really expecting

play06:41

‫that it would increase three times?

play06:44

‫I mean with what we already know,

play06:46

‫we should know that this here could never work.

play06:51

‫So let's see why that is.

play06:53

‫So right here at the beginning of dysfunction

play06:56

‫likes was zero, right?

play07:00

‫And so then here, setLikes would be zero

play07:02

‫plus 1 equals 1, right?

play07:06

‫So this one is pretty clear, but then what in the next line?

play07:10

‫So what is the value of likes here in this line?

play07:14

‫Well, it is actually still zero.

play07:17

‫And so that's because the state update

play07:20

‫is once again, asynchronous.

play07:23

‫So we do not get access to the new state value

play07:26

‫after this line of code right here.

play07:28

‫And so this is exactly what happens down here.

play07:32

‫So here, the state is now stale,

play07:35

‫so as we learned in the previous lecture as well.

play07:39

‫So we can very easily see that here again

play07:41

‫with this console.log.

play07:45

‫So if I click again, and actually I want the other one.

play07:49

‫So this one here, well then you see that it became two,

play07:54

‫which is exactly the value that we had before.

play07:57

‫And so here it was 2 plus 1 made this new 3.

play08:01

‫But here, it was still 2, and here as well,

play08:03

‫and here as well.

play08:05

‫So how could we make this work

play08:07

‫if we really wanted to update the state

play08:09

‫three times like here?

play08:12

‫I mean, of course, we could just do this,

play08:15

‫but this is not the point here.

play08:17

‫So we are trying to learn how we could do this right here

play08:20

‫in another way.

play08:22

‫So actually, we have been doing that all along.

play08:26

‫So all the time, whenever we were updating state

play08:30

‫based on the current state,

play08:32

‫we would use a callback function instead of just a value.

play08:36

‫So we also talked about that in the previous lecture.

play08:39

‫And so now the time came where we really learn

play08:43

‫why we have been doing it with the callback function

play08:46

‫all the time.

play08:48

‫So let's remove this here or comment it out.

play08:55

‫And then let's do it the right way.

play08:58

‫So setLikes, and now we pass in the callback function.

play09:02

‫And then as you already know,

play09:04

‫the first argument here is the current value of the state,

play09:08

‫and then we just return the new one.

play09:11

‫And again here, likes could be called anything.

play09:16

‫Okay, let's do this three times, and then let's reload.

play09:22

‫And now, yeah, now it works.

play09:26

‫So this is the trick that changes the way

play09:29

‫this state is updated.

play09:31

‫So here in the callback function,

play09:33

‫we do actually get access to the latest updated state.

play09:38

‫So initially likes was zero, and then it returned 1.

play09:42

‫And so then in the next call here,

play09:44

‫this likes in this callback function will be 1.

play09:48

‫And so then we can update it

play09:49

‫to another one, and to another one.

play09:52

‫Beautiful.

play09:54

‫And so this is the reason why I've been telling you

play09:57

‫that each time that we set state based on the previous state

play10:01

‫or based on the current state,

play10:04

‫we should always, always use a callback function

play10:07

‫like this here.

play10:09

‫Now you might be wondering like why should we do that here?

play10:13

‫I mean, it works perfectly fine, right?

play10:17

‫And you're right about that.

play10:18

‫It works perfectly fine,

play10:20

‫but we never know what other developers

play10:23

‫might do with our functions,

play10:25

‫or even what we might do later ourselves.

play10:28

‫So let's say that at some point,

play10:30

‫we want to change how this function works,

play10:32

‫and then without thinking about it, we just do this.

play10:36

‫And so then we go back to this not working as expected.

play10:40

‫So now we want to increase the likes by 2,

play10:43

‫but it will still only increase by 1, right?

play10:47

‫Or another situation, maybe, let's comment this one out.

play10:53

‫So maybe, here we could think

play10:55

‫that we could just call this function here three times.

play11:02

‫Or maybe some other developer might think that.

play11:05

‫And so then they would get surprised when they see

play11:08

‫that this is actually not working, right?

play11:11

‫And so again, you should always,

play11:14

‫always use the callback function,

play11:16

‫because then you are always safe for whatever change

play11:20

‫your code goes through in the future.

play11:25

‫So with this, it will now work,

play11:29

‫but of course, we need to write the correct variable name.

play11:35

‫So yeah, now it does work.

play11:39

‫So even if you then use the function somewhere else,

play11:42

‫by doing this, you are safeguarded about well,

play11:46

‫any changes that might occur in the future.

play11:52

‫All right.

play11:53

‫And now to finish, let's just prove

play11:55

‫that automatic batching now works in React 18

play11:59

‫even outside of event handlers.

play12:02

‫So here we have this button that should undo,

play12:06

‫so it should reset our state two seconds later.

play12:11

‫Well, that's easy enough.

play12:13

‫Let's just create a function called handleUndoLater.

play12:23

‫And this function will simply set a timeout,

play12:27

‫and then after two seconds, it'll call handleUndo.

play12:33

‫So after 2000 milliseconds.

play12:35

‫And so what this will do is to schedule

play12:37

‫this handleUndo function to be executed two seconds

play12:42

‫after this function here was called.

play12:45

‫And so then, handleUndo is no longer really

play12:49

‫an event handler function.

play12:50

‫It's just any function that simply gets called

play12:54

‫at a later time.

play12:55

‫So that's just what setTimeout does.

play12:59

‫So let's then wire that up here with the onClick prop.

play13:05

‫So handleUndoLater.

play13:10

‫All right.

play13:12

‫Let's just then set our state.

play13:16

‫Let's clean up here.

play13:17

‫And then I just clicked, and let's wait.

play13:21

‫And indeed, two seconds later, our state was updated.

play13:25

‫And indeed, our component was only rendered once,

play13:29

‫which is proved here by this single render string.

play13:34

‫Great.

play13:35

‫So again, this proves that in React 18

play13:39

‫batching happens not only inside event handlers,

play13:42

‫but also inside a set timeout.

play13:45

‫And the same is true for promises and other situations.

play13:49

‫Now, just to really make sure,

play13:51

‫and you don't have to do this,

play13:53

‫but I like to play around with this stuff.

play13:56

‫So what I want to do now is to render this using React 17.

play14:01

‫So I will comment this one out, and comment this one, okay?

play14:08

‫And then here we need to also change here from here.

play14:11

‫And so now this is basically back

play14:13

‫to being a React 17 application.

play14:16

‫And that's exactly what it says here in this warning.

play14:19

‫So until you switch to the new API,

play14:21

‫your app will behave as if it's running React 17.

play14:25

‫But right now, that's actually exactly what we want.

play14:30

‫So now we get some error here, but yeah.

play14:34

‫So let's do some state updating here.

play14:37

‫Then I will clean and watch what happens

play14:39

‫when I click this button now.

play14:42

‫So let's wait.

play14:43

‫And now we got two re-renders.

play14:47

‫And so this does actually prove that before React 18,

play14:51

‫automatic batching was not happening inside a setTimeout.

play14:57

‫So that's really curious,

play14:59

‫but of course, let's now put it back.

play15:04

‫All right.

play15:06

‫So this was just to show you

play15:07

‫that there really is a difference,

play15:09

‫so that React 18, well really changed this.

play15:15

‫So again, now we should be back to only one.

play15:19

‫Yeah, there we go.

play15:22

‫Okay, and this is actually all I had to show you here.

play15:25

‫So this was a bit longer than expected,

play15:27

‫but we did to a lot of stuff here.

play15:30

‫So after you do a quick recap of everything we just do here,

play15:34

‫or that we did here, actually,

play15:37

‫then let's go to the next lecture.

Rate This

5.0 / 5 (0 votes)

Related Tags
ReactState ManagementBatchingAsynchronous UpdatesCallback FunctionsWeb DevelopmentFront-endJavaScriptPerformance OptimizationTutorial