DEV Community

Siddharth Singh Bhadauriya
Siddharth Singh Bhadauriya

Posted on

Beginners guide to React.js Batched Updates

Overview

A couple of months back when I was learning React and going into deep internet holes to understand every major-minor concept regarding the Why's & How's of them, I stumbled upon React Batched Updates.
I learned how this feature of React acts differently for calling the setState functions synchronously and asynchronously.

To get better understanding consider this example.
It's a simple example to interact with and understand the broader aspect of the difference in the behavior of Batching, or what it used to be recently.

Now with the onset of React 18, it improves efficiency right out of the box by handling more batching by default, eliminating the need to batch updates manually in application. This post will describe batching, how it used to function, and what has changed.

Some definitions first

Batching

Batching is when React groups multiple state updates into a single re-render for better performance.

Why Such a thing ?? Elaborating a bit..

SetState() can be used to update the states of class components, and hooks (i.e. useState()) can be used to update the states of function components. Parts of the component tree are re-rendered as a result of these changes. A simple solution would be to re-render the component after each use to setState(), however this would be inefficient when numerous calls to setState() are made within a React event handler or synchronous lifecycle method.

React implements a batched updating mechanism to reduce the number of component renders. Consequently, multiple state changes will be batched into a single update, which will eventually trigger one re-render of a component.

Again check this example for better clarity and understanding.

In just Recent-Past..

When React batches updates are done in known ways like lifecycle methods or event handlers, React batches them, but not when they are made in callbacks like SetTimeout or Promises. This means that if you make several calls to update the state, React will re-render the component after each call.

After using useState or this.setState to update your component's state, elements of the component re-render depending on the update. More importantly, if you have many calls to update the state within a React event handler like onClick, React does the updates in a batch rather than one at a time, minimizing the number of renderings the component performs.

Example

If two state updates occur inside the same click event, React will always combine them into a single re-render. If you execute the following code, you'll notice that React only renders once for each click, despite the fact that the state is set twice:


function App() {
  const [count, setCount] = useState(0);
  const [flag, setFlag] = useState(false);

  function handleClick() {
    setCount(c => c + 1); // Does not re-render yet
    setFlag(f => !f); // Does not re-render yet
    // React will only re-render once at the end (that's batching!)
  }

  return (
    <div>
      <button onClick={handleClick}>Click on me !!</button>
      <h1 style={{ color: flag ? "yellow" : "purple" }}>{count}</h1>
    </div>
  );
}

Enter fullscreen mode Exit fullscreen mode

This is beneficial to performance because it reduces the number of unwanted re-renders. It also prevents your component from presenting "half-finished" states in which only one state variable has been changed, which could lead to issues and bugs.

Setback: However, React wasn’t consistent about when it batches updates. For example, if you need to fetch data, and then update the state in the handleClick above, then React would not batch the updates, and perform two independent updates.

We only batched updates during the React event handlers, until React 18. By default, React did not batch updates inside of promises, setTimeout, native event handlers, or any other event.

Present-Coming Days Batching Behavior..

Starting in React 18 mostly, all updates will be automatically batched, no matter where they originate from.

Automatic Batching: This means that updates in timeouts, promises, native event handlers, and any other event will batch in the same manner that updates in React events do. Anticipate that this will result in less work being rendered and, as a result, better performance in your apps.

Example

function handleClick() {
  setCount(c => c + 1);
  setFlag(f => !f);
  // React will only re-render once at the end (that's batching!)
}

Enter fullscreen mode Exit fullscreen mode

behaves the same as this:

setTimeout(() => {
  setCount(c => c + 1);
  setFlag(f => !f);
  // React will only re-render once at the end (that's batching!)
}, 1000);


Enter fullscreen mode Exit fullscreen mode

behaves the same as this too:

fetch(/*...*/).then(() => {
  setCount(c => c + 1);
  setFlag(f => !f);
  // React will only re-render once at the end (that's batching!)
})

Enter fullscreen mode Exit fullscreen mode

and also behaves the same as this:

element.addEventListener('click', () => {
  setCount(c => c + 1);
  setFlag(f => !f);
  // React will only re-render once at the end (that's batching!)
});

Enter fullscreen mode Exit fullscreen mode

I hope this helps. It helped me. A programmer just like you. 🌟

Oldest comments (0)