React is a powerful JavaScript library, but some of its behaviors can be tricky to grasp, especially for beginners. One of these concepts is state update batching, which ensures React updates your app's state efficiently. In this article, we will look at how update batching works in React and its impact on application performance, all while addressing common misconceptions and challenges.
What Is State Update Batching?
State update batching is a mechanism in React where multiple state updates are grouped and processed in a single render cycle. This prevents unnecessary re-renders and improves the performance of your application.
Imagine you have a button in your React app that resets three pieces of state when clicked. These states could be:
answer
(a string)best
(another string)solved
(a boolean)
When you click the button, React doesn’t update these states and re-render your app one by one. Instead, React batches all the updates into a single process, updating all three states and re-rendering the app once.
This approach improves performance by:
Reducing unnecessary renders.
Ensuring the UI is updated only when all state changes in an event handler are complete.
Why Does React Batch State Updates?
The primary goal of batching is performance optimization. Without batching, React would render the UI each time a state update occurs, which can lead to inefficiencies and sluggish performance in complex applications.
Think of batching like you had three separate errands to run; it would make sense that you’d group them into one trip instead of going out three times. It’s faster, simpler, and just makes sense.
How Batching Works: A Practical Example
Here’s an example of how React batches state updates:
function App() {
const [answer, setAnswer] = React.useState("");
const [best, setBest] = React.useState("");
const [solved, setSolved] = React.useState(false);
const reset = () => {
setAnswer("");
setBest("");
setSolved(false);
};
return <button onClick={reset}>Reset</button>;
}
When the reset
function is clicked, React updates all three states (answer
best
solved
), batches these updates together, and re-renders the app just once.
Key Insight About React State Updates
State Updates Are Asynchronous
When you update a state, React doesn’t immediately change the variable’s value. Instead, React schedules the updates, and you’ll see the new value only after the re-render.
function App() {
const [answer, setAnswer] = React.useState("old value");
function updateAnswer() {
setAnswer("New Answer");
console.log(answer); // Logs the old value, not "New Answer".
}
}
To access the most recent state value during an update, use the callback form of setState
:
function App() {
const [answer, setAnswer] = React.useState("old value");
function updateAnswer() {
setAnswer((prevAnswer) => prevAnswer + " updated");
console.log(answer); // Logs the "New Answer".
}
}
React 18: Batching Everywhere
Before React 18, batching only worked inside event handlers (like onClick
). If you used timeouts or promises, React would update each state separately, causing multiple renders.
With React 18, batching works everywhere! Whether it’s a timeout, a promise, or even a custom DOM event, React now batches all updates automatically.
setTimeout(() => {
setAnswer("");
setBest("");
setSolved(false);
}, 1000);
In this case, React batches the updates and triggers a single render.
When Batching Doesn't Work
In rare cases, there might be times when you don’t want React to batch updates. In such cases, you can use ReactDOM.flushSync
to force React to apply the updates immediately.
import { flushSync } from "react-dom";
flushSync(() => {
setAnswer("");
});
However, you probably won’t need this unless you’re dealing with very advanced scenarios.
Benefits of State Update Batching
Improved Performance: Reduces the number of re-renders and optimizes resource usage.
Cleaner Code: Eliminates the need to manually manage multiple re-renders for related updates.
Consistency: Ensures that related state changes appear together in the UI.
Conclusion
State update batching is one of React's many features that improve app performance while keeping your code clean and efficient. By batching updates, React minimizes unnecessary re-renders and ensures your app remains fast. With the introduction of React 18, batching has become even more powerful and consistent across different contexts.
PS: This article is as a result of my learning from Jonas Schmedtmann React’s course.