Skip to main content

Incorrect State Update

This example illustrates a common mistake made by React beginners when updating state.
React state updates are not immediate; instead, they are batched for performance reasons.

When setState or setCount is called multiple times in a row with a simple increment (e.g., setCount(count + 1)), all calls will use the same initial state value, leading to unexpected behavior.

To correctly update the state based on its previous value, you should use a callback function like setCount(prevCount => prevCount + 1). This ensures that each state update correctly increments the previous value.

import { useState } from "react";

const First = () => {
// updating current state isn't immediate
const [count, setCount] = useState(0);

const handleClick = () => {
setCount(count + 1);

// setCount(count + 1);
// setCount(count + 1); // this won't work as expected because it essentially does 0 + 1 or uses the initial state value
// the updates are scheduled for future execution - when React batches updates

/*
Bundling Explanation
"Bundling" in the context of React and state updates refers to the mechanism that React uses to optimize
performance by grouping (bundling) multiple state updates into a single component update.
This avoids unnecessary re-renders of the component and thus improves the application's performance.

When you call setState (or setCount in this case) multiple times in a row, React may group these
calls and perform them together at the next component render. However, if you do not use the callback function,
all of these calls will use the same state value and essentially overwrite each other.
*/

// this solution correctly increments the value because it uses a callback
// setCount(prevCount => prevCount + 1); // prevCount = 0 -> prevCount + 1 = 1
// setCount(prevCount => prevCount + 1); // prevCount = 1 -> prevCount + 1 = 2
// setCount(prevCount => prevCount + 1); // prevCount = 2 -> prevCount + 1 = 3
};

return (
<div className="flex flex-col items-center justify-center h-screen">
<button
onClick={handleClick}
className="bg-blue-500 px-4 py-2 text-white rounded mb-5"
>
Click me!
</button>

<p>Count is: {count}</p>
</div>
);
};

export default First;