State Update Batching | Lecture 132 | React.JS 🔥

The Coding Classroom
5 Dec 202309:11

Summary

TLDRThis video script delves into the intricacies of React's state update batching process. It explains how React optimizes performance by batching multiple setState calls into a single state update, triggering only one re-render instead of multiple. The speaker illustrates this concept through code examples, highlighting the asynchronous nature of state updates and the potential for stale state before the re-render. Additionally, the script covers React 18's improved batching capabilities, extending automatic batching to situations like timeouts and promises, and mentions rare cases where disabling batching might be necessary.

Takeaways

  • 🤝 React batches multiple state updates in event handlers into a single re-render for better performance.
  • ⌚ Accessing the state variable immediately after calling setState will return the stale (previous) value, as the state update is asynchronous and only reflected after re-render.
  • 📤 If you need to update state based on the previous state update in the same event handler, pass a callback function to setState instead of a value.
  • 🆕 React 18 introduced automatic batching for state updates triggered outside React event handlers, such as timeouts, promises, and native events.
  • ⚠️ In rare cases where automatic batching causes issues, you can wrap the problematic state update in ReactDOM.flushSync() to exclude it from batching.
  • 🧩 Batching state updates makes sense conceptually, as it represents a single new view rather than multiple partial updates.
  • ⚡ Avoiding unnecessary re-renders by batching state updates is a performance optimization provided by React out-of-the-box.
  • 🔄 Before React 18, state updates triggered outside React event handlers were not batched, leading to multiple re-renders.
  • 🧐 Understanding batching is important, especially when working with older React versions where it behaved differently.
  • 🎥 The video provides a detailed explanation of state update batching in React, a crucial concept for optimizing performance.

Q & A

  • What is state batching in React?

    -State batching in React refers to the mechanism where multiple state updates within the same event handler are combined into a single re-render. Instead of triggering a re-render for each individual state update, React batches these updates together and performs only one re-render.

  • Why does React batch state updates?

    -React batches state updates for performance optimization. If multiple state updates are related and meant to represent a new view, it would be inefficient to trigger multiple re-renders for each update. Batching ensures that only one re-render occurs, which improves the application's performance.

  • Can you access the updated state immediately after calling the setState function?

    -No, you cannot access the updated state immediately after calling the setState function. The state update is asynchronous, and the new state value is only available after the re-render cycle has completed. Attempting to access the state variable right after calling setState will still give you the previous (stale) state value.

  • How can you update state based on the previous state value in the same event handler?

    -To update state based on the previous state value within the same event handler, you can pass a callback function to the setState function instead of a single value. The callback function receives the previous state as an argument and returns the new state based on that value.

  • Did React batch state updates in all situations before React 18?

    -No, before React 18, state updates were only batched in event handlers triggered by browser events (e.g., click, submit). Updates triggered outside of event handlers, such as timeouts, promises, or native event handlers, were not batched automatically.

  • What is the behavior of state batching in React 18 and later versions?

    -In React 18 and later versions, state updates are batched automatically in all situations, including timeouts, promises, and native event handlers. This improvement enhances performance by reducing unnecessary re-renders.

  • Is there a way to opt-out of automatic batching in React?

    -Yes, in rare cases where automatic batching might cause problems, you can opt-out by wrapping the problematic state update within the ReactDOM.flushSync function. This will exclude that specific update from being batched.

  • Why is it important to understand state batching in React?

    -Understanding state batching is crucial because it affects the way you work with state updates and can have surprising results if not accounted for. It also helps in writing more efficient and performant React applications by avoiding unnecessary re-renders.

  • Can state batching lead to unexpected behavior if not handled properly?

    -Yes, state batching can lead to unexpected behavior if not handled properly. For example, if you try to access the state value immediately after calling setState, you might get the previous (stale) state value instead of the updated one, which could cause bugs or unintended behaviors.

  • How does state batching relate to the overall render lifecycle in React?

    -State batching is an important part of the render lifecycle in React. It occurs during the initial triggering phase, where React collects all state updates that need to be applied. The batched updates are then processed during the render phase, and a single re-render is triggered, followed by the commit phase.

Outlines

00:00

📚 State Update Batching in React

This paragraph explains the concept of state update batching in React. It clarifies that when multiple state variables are updated within the same event handler, React batches these updates into a single state update, triggering only one re-render and commit phase. This behavior serves as a performance optimization, avoiding unnecessary re-renders. The paragraph also highlights that immediately after a state update, the state variable still holds the previous value until the re-render occurs, a concept known as 'stale state'.

05:03

💡 Advanced Batching Scenarios and React 18

This paragraph discusses advanced scenarios where state update batching becomes relevant, such as timeouts, promises, and native DOM event handlers. Before React 18, batching only occurred in event handlers, but React 18 introduced automatic batching in these other situations for better performance. The paragraph also mentions the ReactDOM.flushSync function to exclude specific updates from batching in rare problematic cases. It concludes by emphasizing the importance of understanding batching behavior, especially when working with older React versions.

Mindmap

Keywords

💡Render phase

The render phase refers to the stage in React's lifecycle where it determines what changes need to be made to the DOM tree based on the updated state and props. In the video, the render phase is mentioned in the context of explaining when state updates are actually applied and when React triggers a re-render.

💡Key prop

The key prop is a special string attribute in React that helps identify which items in a list have changed, been added, or been removed. This helps React optimize re-rendering and update the DOM efficiently. The video mentions that the key prop's behavior is one of the aspects of the render phase that has been covered in depth.

💡State updates

State updates refer to the process of modifying the state object in a React component. When the state is updated, React will re-render the component and its children with the new state values. The video focuses on explaining how React handles multiple state updates and batches them together for performance optimization.

💡Batching

Batching is a performance optimization technique used by React to group multiple state updates together and perform a single re-render instead of re-rendering for each individual update. This is particularly useful when multiple state variables are updated in a single event handler or lifecycle method. The video explains how React automatically batches state updates in different scenarios.

💡Asynchronous state updates

Asynchronous state updates refer to the fact that when you call the state setter function (e.g., setState or the updater function from useState), React doesn't update the state immediately. Instead, React batches these updates and applies them later, during the next re-render cycle. The video explains this concept and its implications, such as state variables appearing 'stale' immediately after updating them.

💡Callback function

In the context of state updates, a callback function can be passed to the state setter function (e.g., setState) instead of a value. This callback function receives the previous state as an argument and returns the new state value. This is useful when the new state depends on the previous state, as demonstrated in the video.

💡React 18

React 18 is the latest major version of the React library at the time the video was created. One of the improvements introduced in React 18 is automatic batching of state updates in more scenarios, such as timeouts, promises, and native events, which previously did not benefit from automatic batching.

💡ReactDOM.flushSync

ReactDOM.flushSync is a method provided by React that allows you to bypass the automatic batching of state updates for a specific section of code. This can be useful in rare situations where batching might cause issues, although the video mentions that this is unlikely to be needed in most cases.

💡Performance optimization

Performance optimization refers to techniques and strategies aimed at improving the overall performance and efficiency of a web application or user interface. In the context of the video, features like batching state updates and automatic batching in React 18 are presented as performance optimizations provided by React out of the box.

💡Fiber tree

The fiber tree is a data structure used internally by React to represent the component hierarchy and manage updates efficiently. The video mentions that component state is stored in the fiber tree during the render phase, which is why state variables appear 'stale' immediately after updating them, as the render phase hasn't completed yet.

Highlights

React batches multiple setState calls into a single state update for the entire event handler, triggering only one re-render and commit phase.

Batching state updates is a performance optimization in React, as it avoids unnecessary re-renders and wasted renders.

When referencing a state variable immediately after updating it, the variable still holds the previous state value until the re-render occurs.

Updating state in React is asynchronous because the updated state is only available after the re-render, not immediately after the setState call.

To update state based on the previous state in the same event handler, use a callback function with setState instead of passing a single value.

Before React 18, automatic batching only occurred in event handlers, but not in situations like timeouts, promises, or native DOM events.

React 18 introduced automatic batching everywhere in the code, including timeouts, promises, and native DOM events.

In rare situations where automatic batching is problematic, you can use ReactDOM.flushSync to exclude a state update from batching.

Batching state updates is a performance optimization that avoids unnecessary re-renders and wasted renders.

When referencing a state variable immediately after updating it, the variable still holds the previous state value until the re-render occurs.

Updating state in React is asynchronous because the updated state is only available after the re-render, not immediately after the setState call.

To update state based on the previous state in the same event handler, use a callback function with setState instead of passing a single value.

Before React 18, automatic batching only occurred in event handlers, but not in situations like timeouts, promises, or native DOM events.

React 18 introduced automatic batching everywhere in the code, including timeouts, promises, and native DOM events.

In rare situations where automatic batching is problematic, you can use ReactDOM.flushSync to exclude a state update from batching.

Transcripts

play00:01

‫So we have dived really deep

play00:03

‫into some aspects of the render phase,

play00:06

‫like the rules for render logic, and how the key prop works.

play00:10

‫But now let's take one step back,

play00:13

‫and go back to one very important aspect

play00:16

‫of the first triggering phase,

play00:18

‫which is the fact that state updates are batched.

play00:23

‫So in that first lecture about how rendering works,

play00:27

‫we had this sentence, which says

play00:30

‫that renders are not triggered immediately.

play00:33

‫And so in this lecture I want to focus on this part

play00:37

‫which says that there is also batching

play00:40

‫of multiple setState calls.

play00:44

‫Now, as always, the easiest way of explaining

play00:47

‫difficult concepts is by using a small code example.

play00:51

‫So here we have three pieces of state,

play00:54

‫defined using the useState hook,

play00:57

‫and we also have a button in the user interface.

play01:00

‫Then whenever there is a click on the button,

play01:03

‫the event handler function named reset is called.

play01:07

‫In this function, the three pieces of state,

play01:10

‫answer, best, and solved,

play01:13

‫are basically reverted back to their original state

play01:17

‫and therefore, this function is called reset.

play01:20

‫Now, actually this is the part

play01:22

‫that interests us in this lecture.

play01:25

‫And so let's now focus only on the event handler function.

play01:30

‫Now what I want to do here is to analyze

play01:32

‫how these three pieces of state

play01:35

‫are actually updated behind the scenes.

play01:38

‫So we might think that, as React sees

play01:41

‫the set answer function call,

play01:43

‫it would update the state to the empty string as requested,

play01:48

‫and then trigger a re-render, and the commit phase,

play01:52

‫then it would move on to the next line,

play01:54

‫and to the same thing again,

play01:57

‫and finally do the entire thing

play01:59

‫one more time for the third state update.

play02:03

‫So intuitively, we would think that,

play02:05

‫if there are three state variables

play02:08

‫being updated in this event handler,

play02:10

‫then React would re-render three times, right?

play02:14

‫However, this is actually not how it works.

play02:18

‫So this is not how React updates multiple pieces of state

play02:23

‫in the same event handler function.

play02:25

‫Instead, these state updates will actually get batched

play02:29

‫into just one state update for the entire event handler.

play02:34

‫So updating multiple pieces of state

play02:37

‫won't immediately cause a re-render for each update.

play02:40

‫Instead, all pieces of state inside the event handler

play02:44

‫are updated in one go.

play02:46

‫So they are batched, and only then

play02:49

‫will React trigger one single render and commit.

play02:54

‫And conceptually, it makes sense that React works this way,

play02:58

‫because if we're updating these pieces of state together,

play03:02

‫it probably means that they should just represent

play03:05

‫one new view, and therefore,

play03:07

‫React only updates the screen once.

play03:10

‫So if these date updates belong together,

play03:14

‫it really wouldn't make much sense

play03:16

‫to update the screen three times.

play03:19

‫Doing so would also create two wasted renders,

play03:23

‫because we're not interested in the first two renders,

play03:26

‫only the final one, which already contains

play03:29

‫all the three state updates.

play03:32

‫Therefore, the fact that React

play03:34

‫automatically batches state updates in this way

play03:37

‫is yet another performance optimization

play03:40

‫that React gives us out of the box.

play03:43

‫Now, batching state updates is extremely useful,

play03:47

‫but it can also have surprising results.

play03:50

‫So let's turn our attention to this line of code now,

play03:54

‫where we reference the answer state variable

play03:57

‫right after updating it.

play03:59

‫So what do you think will be the value

play04:02

‫of this variable at this point?

play04:04

‫Well, let's try to think about this.

play04:07

‫So remember, that component state is stored

play04:11

‫in the fiber tree during the render phase.

play04:15

‫Now, at this point in the code,

play04:17

‫the render phase has not happened yet.

play04:20

‫So React is still reading the function line by line

play04:24

‫to figure out what state needs to be updated,

play04:27

‫but it hasn't actually updated the state yet,

play04:30

‫and it also hasn't re-rendered yet.

play04:33

‫That's the whole point of batching state updates

play04:36

‫in the first place, right?

play04:38

‫So what this means is that, at this point of the code,

play04:43

‫the answer variable will still hold the current state.

play04:47

‫So the state before the update,

play04:50

‫even though we already told React to update it.

play04:53

‫So at this point we say that our state is stale,

play04:58

‫meaning that the state is no longer fresh and updated,

play05:02

‫because in fact, a state update will only be reflected

play05:06

‫in the state variable after the re-render.

play05:10

‫And so for this reason, we say that updating state in React

play05:14

‫is asynchronous, and again, it is asynchronous

play05:19

‫because React does not give us the updated state variable

play05:23

‫immediately after the set answer call,

play05:26

‫but only after the re-render has happened.

play05:31

‫Now, the same thing is also true

play05:33

‫whenever there is only one piece of state being updated.

play05:37

‫So no matter how many state variables are being updated,

play05:41

‫the updated state is only available

play05:44

‫after the re-render, not immediately.

play05:47

‫Now, sometimes we actually do need the new value

play05:52

‫immediately after updating it, and in the case,

play05:56

‫that we need the new value

play05:57

‫in order to update the same state again.

play06:00

‫Or in other words, if we need to update state based

play06:03

‫on a previous state update in the same event handler,

play06:07

‫we can pass a callback function into the set state function

play06:11

‫instead of a single value.

play06:13

‫And we have actually done this in practice

play06:16

‫all the time, right?

play06:20

‫Now, so far, we have only talked about batching

play06:23

‫in event handler functions, like our reset function.

play06:27

‫That's because before React 18,

play06:30

‫React only did automatic batching in event handlers,

play06:34

‫but not in situations that happen

play06:37

‫after a browser event has already happened.

play06:40

‫However, there are certain very important situations

play06:43

‫in which we do need to update state,

play06:46

‫long after a browser event, like a click, has happened.

play06:50

‫Examples of that are timeouts and promises,

play06:54

‫for instance, we might want to run our reset function

play06:59

‫only a second after a click event,

play07:01

‫or we might want to run it after some data has been fetched.

play07:06

‫So it would be nice to also have automatic batching

play07:09

‫in those situations to improve performance, right?

play07:14

‫Well, that's actually one of the important features

play07:17

‫that React 18 gave us.

play07:20

‫So before React 18, if this reset function

play07:24

‫was called by a timeout, or by a promise,

play07:27

‫state updates inside the function would not be batched.

play07:31

‫Instead, in these situations, React would actually

play07:35

‫update the state variables one by one, and therefore,

play07:39

‫in this case, render three times.

play07:42

‫Now another case is handling native events using DOM methods

play07:46

‫such as addEventListener, where state updates

play07:50

‫also used to not be batched, but now they are.

play07:54

‫So again, if you're using the latest React version,

play07:58

‫you will now get automatic batching all the time,

play08:01

‫everywhere in your code.

play08:03

‫And if, for some reason, you are working

play08:06

‫with an older version of React, maybe at your work,

play08:09

‫it's important that you know that batching used to work

play08:13

‫in a different way before version 18.

play08:16

‫Now, there are also some extremely rare situations

play08:19

‫in which automatic batching can be problematic.

play08:23

‫So if you ever find yourself in a situation like that,

play08:26

‫you can just wrap the problematic state update

play08:29

‫in a ReactDOM.flushSync function,

play08:33

‫and React will then exclude that update from batching.

play08:37

‫But you will most likely never need this.

play08:40

‫I'm just mentioning this here,

play08:42

‫so that you know that it exists.

play08:44

‫Now, okay, and that's it about state update batching.

play08:49

‫It turned out to be a bit longer than I thought,

play08:53

‫but as always, there is just

play08:54

‫so much interesting stuff to learn,

play08:57

‫and so I hope that you don't mind at all.

play09:00

‫But in any case, let's quickly go to the next video,

play09:04

‫so I can show you some of this in practice.

Rate This

5.0 / 5 (0 votes)

Related Tags
ReactState ManagementPerformance OptimizationAsynchronous UpdatesBatchingReact 18Event HandlersTimeoutsPromisesTechnical Concepts