DEV Community

Cover image for Understanding how React handles state updates.
Anmol Tiwari
Anmol Tiwari

Posted on

Understanding how React handles state updates.

As someone who has experienced being a new JavaScript developer and attempted to learn React after grasping the fundamentals of state and its management at the component level, I've noticed that confusion can arise regarding the synchronicity of the state setter returned by the useState hook. In this situation, My objective is to offer a brief explanation of how React manages state updates.

Consider this code snippet:

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

  const onClickHandler = () => {
    setCount(count + 1);
  };

  return (
    <div className="App">
      <h3>{count}</h3>
      <button onClick={onClickHandler}>Increment</button>
    </div>
  );
}
Enter fullscreen mode Exit fullscreen mode

In the above scenario, what can be inferred is that, on click of the button, the setCount will increment the state count by 1. Pretty straight forward.

Now consider the following change in the above code:

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

  const onClickHandler = () => {
    for (let i = 0; i < 100; i++) {
      setCount(count + 1); 
    }
  };

  return (
    <div className="App">
      <h3>{count}</h3>
      <button onClick={onClickHandler}>Increment</button>
    </div>
  );
}
Enter fullscreen mode Exit fullscreen mode

In this scenario, you will see that essentially the state updates just once and count value becomes 1 on a single click.

To understand what just happened, we would have to understand how state updates are characterised in React. Primarily, they are not asynchronous. But what makes them a bit peculiar than other synchronous functions is that state updates in React are scheduled in a Queue. Now, React updates the state, hence causing a re-rendering of the view if needed, but updates are committed on its own whims to enhance rendering performance. React may delay it, and then update several components in a batch. So essentially in the above component, the entire for loop runs adding a bunch of state updates in the queue but what matters is that the count value inside setCount(count + 1) is still 0, which means referencing the state right after updating it is pitfall to be avoided at all cost. Upon encountering the last setCount, the value of count is still 0 and hence it's incremented.

Now there is another way to reference current state inside a state update method:

function App() {
  const [count, setCount] = useState(0);
  console.log("Rendered");
  const onClickHandler = () => {
    for (let i = 0; i < 100; i++) {
      setCount((currCount) => currCount + 1);
    }
  };

  return (
    <div className="App">
      <h3>{count}</h3>
      <button onClick={onClickHandler}>Increment</button>
    </div>
  );
}
Enter fullscreen mode Exit fullscreen mode

What will be observed is in this case we will see the state of count updated to 100 on a single click. The reason being the added callback is going to be executed post the previously scheduled state update and in process providing the updated state value.

Hope reading through this article helped you get a fresh perspective to React state updates.

Top comments (0)