Home/Learn/React/Rendering and Reconciliation — What Happens on a State Change

Rendering and Reconciliation — What Happens on a State Change

Intermediate
Fundamentals

A render is React calling your function, not React touching the DOM. Separating those two ideas explains re-render behaviour, keys, and most performance advice.

Overview

People assume a re-render means the DOM was rebuilt, which makes every re-render sound expensive and leads to premature optimisation everywhere. What actually happens is two phases: React calls your component functions to produce a description of the UI, compares it with the previous description, and only then applies the minimal set of DOM changes. Calling a function is cheap; touching the DOM is not. Understanding the split tells you which re-renders are worth caring about and why a component re-renders when its parent does even if its props never changed.

Render, Then Commit

Two phases with very different costs.

The four steps of an update
// 1. TRIGGER   — initial mount, or a state update in this component
//                 or in one of its ancestors
// 2. RENDER    — React calls your function. It must be PURE: no DOM
//                 writes, no fetches, no mutating outside variables.
//                 The output is a description, not DOM.
// 3. COMMIT    — React diffs against the previous description and
//                 applies only what changed to the real DOM.
// 4. EFFECTS   — after the browser paints, effects run.

// So this component re-renders (function called) but produces the
// same output, and the commit phase does nothing at all:
function Header() { return <h1>AiCanCode</h1> }

// "It re-rendered" is not automatically a problem. The question is
// whether the render did expensive work, or produced DOM changes.

What Triggers a Re-render

Three causes, and one common misconception.

Own state, parent render, or context
// 1. Its own state changed
setCount(c => c + 1)

// 2. Its parent re-rendered — children re-render by default,
//    regardless of whether their props changed
function Parent() {
  const [n, setN] = useState(0)
  return <><button onClick={() => setN(n+1)} /><Child /></>  // Child re-renders
}

// 3. A context it consumes changed value

// NOT a trigger: mutating an object without setState
user.name = 'New'          // React never hears about this
setUser({ ...user, name: 'New' })   // this is the update

// Setting state to the SAME value bails out early
setStatus('idle')          // already 'idle' -> no re-render
// but only for Object.is equality — a new object with identical
// contents is a different value and does re-render.

How the Diff Works

Two rules cover React's reconciliation, and both have practical consequences.

Type and position decide identity
// Rule 1: different element TYPE at the same position
//         -> destroy the whole subtree and rebuild it, state included
{isEditing ? <Editor value={v} /> : <Preview value={v} />}
// Switching modes unmounts one and mounts the other. Any internal
// state in Editor is gone. That is usually what you want.

// Same type, different props -> keep the DOM node, update attributes
<input className="a" />  ->  <input className="b" />   // node reused

// Rule 2: within a list, position is identity unless you give keys
// (this is exactly why the index-key bug exists)

// The consequence people trip on: a component's state is tied to
// its POSITION in the tree, not to its name.
{isPro ? <Counter /> : <Counter />}     // same type, same position
// -> the SAME component instance, state preserved across the toggle
{isPro ? <Counter key="pro" /> : <Counter key="free" />}
// -> different keys, so React treats them as different instances

Key Points to Remember

  • 1Rendering calls your function to produce a description; committing applies the minimal DOM changes
  • 2A re-render is cheap unless it does expensive work or produces actual DOM changes
  • 3A component re-renders when its own state changes, its parent re-renders, or a consumed context changes
  • 4Mutating an object does not trigger anything — React compares with Object.is, so pass a new value
  • 5State belongs to a position and type in the tree, so changing the type or the key resets it

Interview Questions

Sign in to ask Aria
1

What is the difference between the render phase and the commit phase?

Medium
2

A child component re-renders even though its props did not change. Why?

Medium
3

Why does React reset a component's state when its element type changes at the same position?

Hard

Ask Aria about Rendering and Reconciliation — What Happens on a State Change

Your personal AI tutor — ask anything about this concept

Revision Status

Personal Notes

Sign in to save personal notes for this topic.

Discussion

Sign in to join the discussion.

Loading discussion…