Unlocking Efficient State Updates in React
The Power of Batched Updates
When working with React, you’ve likely encountered situations where updating your component’s state triggers multiple re-renders. This can lead to performance issues and make your application feel sluggish.
By default, React batches updates made within event handlers or lifecycle methods, reducing the number of re-renders. However, when updates are made within callbacks like Promises or SetTimeout, React updates the state synchronously, leading to multiple re-renders.
A Real-World Example
Consider a scenario where you have two state values, item1
and item2
, and you update their values when either of two buttons is clicked.
const initialState = {
item1: '',
item2: '',
};
function MyComponent() {
const [state, setState] = useState(initialState);
const handleClick1 = () => {
Promise.resolve().then(() => {
setState({ item1: 'New value 1' });
setState({ item2: 'New value 2' });
});
};
const handleClick2 = () => {
setState({ item1: 'New value 1' });
setState({ item2: 'New value 2' });
};
return (
);
}
When you click the first button, which updates the state within a Promise, the component re-renders twice. But when you click the second button, which updates the state within an event handler, the component re-renders only once.
Forcing Batched Updates
To overcome this limitation, you can wrap your state update calls in ReactDOM.unstable_batchedUpdates()
. This ensures that React batches the updates, resulting in only one re-render.
const handleClick1 = () => {
Promise.resolve().then(() => {
ReactDOM.unstable_batchedUpdates(() => {
setState({ item1: 'New value 1' });
setState({ item2: 'New value 2' });
});
});
};
While the method’s name might raise concerns about its stability, the React team has encouraged its use in production.
When to Use Batched Updates
Before reaching for unstable_batchedUpdates()
, take a step back and assess whether you can refactor your code to make fewer state update calls. In many cases, multiple calls can be replaced with a single call.
- Refactor your code to make fewer state update calls.
- Consider using currying to compose the update values.
Hooks and Batched Updates
The concept of batched updates also applies to Hooks. When using multiple state objects in a functional component, it may be a sign that the component is violating the Single Responsibility Principle.
- Consider combining the state objects.
- Separate them into independent components.
By understanding when to use unstable_batchedUpdates()
and refactoring your code to minimize state update calls, you can create faster and more efficient React applications.