Understanding React’s Render Process: Render Phase, Commit Phase, and Batching Mechanism
React’s rendering model is often described as “declarative,” but behind the scenes, React performs a surprisingly complex sequence of operations to update the UI efficiently. Understanding how React renders, commits changes to the DOM, and batches state updates gives you deep insight into performance, debugging, and how React’s concurrent features (introduced in React 18) actually work.
1. Why Understanding the Render Process Matters
Understanding the render process helps you answer questions like:
In my previous article,
2. The Two Major Rendering Phases
React’s rendering pipeline consists of
2.1. The Render Phase (Reconciliation Phase)
The Render Phase is React’s “planning” stage.
During this phase:
This is why in StrictMode, components render twice: React is ensuring your render logic is
Render Phase = Calculate what should change.
No visible updates occur yet.
2.2. The Commit Phase
Once the Render Phase completes successfully, React enters the Commit Phase.
Unlike the Render Phase, the Commit Phase:
Commit Phase = Apply changes to the screen.
This is the moment the UI actually updates.
In my earlier
During reconciliation, React:
Good keys help React
Bad keys force React to
A helpful way to visualize this is a before/after Fiber tree diagram, showing which nodes React reuses and which it regenerates based on new props or state.
3. Batching: The Secret to Efficient Rendering
Batching is React’s strategy for improving performance by grouping multiple state updates into
Instead of re-rendering a component after every individual setState call, React collects updates and processes them together.
This prevents unnecessary work and ensures smoother UI updates.
Example expectation vs reality:
setCount(c => c + 1) setName("Halis") setFlag(true)
Not three renders → just one.
Batching makes React predictable and efficient.
React’s render cycle is expensive—every render triggers reconciliation, prop/state evaluation, and potential DOM changes. Without batching, even small user interactions could create dozens of renders.
Batching helps React:
Batching is one of the key pillars that makes React performant at scale.
3.1 Batching Before React 18 (The Old Behavior)
Prior to React 18, batching only worked inside:
But
setTimeout(() => {
setA(1) // render
setB(2) // render
}, 1000)
This meant async state updates caused
This inconsistency became a bigger issue as applications increasingly relied on async logic—REST requests, GraphQL, WebSockets, timers, or async form validation.
3.2 Automatic Batching in React 18 (The New Standard)
React 18 introduced
Automatic batching now applies to:
This solved one of the oldest inconsistencies in React’s behavior.
Batching is powerful, but React allows you to
3.3 When Batching Does NOT Apply
import { flushSync } from 'react-dom'
flushSync(() => { setCount(1) // forces immediate render }) setName("John") // batched separately
3.4 Why Batching Matters in Real Applications
Batching has a visible impact on everyday app behavior:
✔ Forms
Multiple setValue or RHF internal updates → fewer renders.
✔ API libraries (React Query, RTK Query)
Cache updates fire many state changes internally → batching prevents “render explosions.”
✔ Animations & transitions
React batches rapid updates to maintain smoothness.
✔ Lists & complex layouts
Avoids heavy re-renders during interactions.
Batching is not just an optimization—it’s essential for scalability.
3.5 How Batching Interacts With the Render and Commit Phases
This ties batching back to the earlier sections of your article:
This unified pipeline is the reason React apps stay responsive even under heavy updates.
Understanding how React batches updates and orchestrates the Render and Commit phases gives you the clarity to reason about performance, avoid unnecessary re-renders, and design components that work
See you in the next deep dive. 👋