DEV Community

Cover image for How to Build a React Hook That Batches Multiple State Updates Automatically
HexShift
HexShift

Posted on • Edited on

How to Build a React Hook That Batches Multiple State Updates Automatically

React already batches updates inside event handlers, but outside of those — like in setTimeout or Promise callbacks — you might hit multiple renders. Here’s how to create a custom hook that forces batching everywhere, minimizing re-renders and saving performance without needing external libraries like Recoil or Jotai.

Why Manual Batching Matters

Use cases where batching helps:

  • Complex forms with many fields updated in sequence
  • Animations or state transitions tied to promises or timers
  • Micro-optimizing deeply nested component trees

Step 1: Create a useBatchState Hook

// useBatchState.js import { useState, useRef } from "react"; import { unstable_batchedUpdates } from "react-dom"; // Works in React 18+ export function useBatchState(initialState) { const [state, setState] = useState(initialState); const pending = useRef([]); function batchUpdate(updater) { pending.current.push(updater); } function flush() { if (pending.current.length === 0) return; unstable_batchedUpdates(() => { setState(prev => { return pending.current.reduce((acc, fn) => fn(acc), prev); }); }); pending.current = []; } return [state, batchUpdate, flush]; } 

Step 2: Using the Hook

// ExampleComponent.js import { useBatchState } from "./useBatchState"; function ExampleComponent() { const [count, batchUpdate, flush] = useBatchState(0); function complexIncrement() { batchUpdate(prev => prev + 1); batchUpdate(prev => prev + 1); batchUpdate(prev => prev + 1); flush(); // Forces all updates to apply at once } return ( <div> <p>Count: {count}</p> <button onClick={complexIncrement}>Increment by 3</button> </div> ); } export default ExampleComponent; 

Step 3: Notes on React 18+

React 18 batches most things by default, but custom hooks like this still give you absolute control for rare cases or legacy codebases that need it.

Pros and Cons

✅ Pros

  • Fewer renders = faster UI for complex state interactions
  • No external dependencies
  • Works across async event boundaries

⚠️ Cons

  • Manual flushing required — if you forget it, you'll have stale updates
  • Can overcomplicate simple cases — don't overuse unless profiling says it's needed

🚀 Alternatives

  • React 18 automatic batching: Works out of the box for most cases, but not 100% for all async flows.
  • State libraries like Jotai, Recoil: Handle fine-grained state natively with batched atoms/selectors.

Summary

Smart batching gives you superpowers when optimizing performance-critical components. Use it when profiling shows wasteful renders — not just because you can.

For a much more extensive guide on getting the most out of React portals, check out my full 24-page PDF file on Gumroad. It's available for just $10:

Using React Portals Like a Pro.

If you found this useful, you can support me here: buymeacoffee.com/hexshift

Top comments (0)

Some comments may only be visible to logged-in visitors. Sign in to view all comments.