Explain what people mean by “Virtual DOM” in React (React element tree in memory), how React re-renders to produce a new tree, how reconciliation (diffing + heuristics + keys) computes changes, and how the commit phase applies DOM mutations. Emphasize: re-render ≠ DOM update.
What is the Virtual DOM in React, and how does it relate to reconciliation?
Use guided tracks for structured prep, then practice company-specific question sets when you want targeted interview coverage.
Core idea
In React, “Virtual DOM” usually means: an in-memory tree representation of your UI (React elements / fibers), not the browser DOM itself. On each update, React re-runs components to produce a new tree, then reconciles it with the previous tree to decide what must change. Only after that, React commits the necessary changes to the real DOM.
Claim | Accurate? | Better wording / why it matters |
|---|---|---|
“VDOM is a copy of the real DOM.” | ⚠️ half-true | It’s a JS representation of the UI ( |
“React updates the minimal set of DOM changes.” | ⚠️ usually | React uses reconciliation heuristics. With stable keys/types, it’s very efficient, but it’s not a perfect minimal-edit solver. |
“Re-render means the DOM changed.” | ❌ | Re-render means React re-ran components to compute a new UI tree. DOM mutations only happen in the commit phase if something actually differs. |
“VDOM makes React fast.” | ⚠️ incomplete | The win is: predictable re-rendering + efficient diffing + batching. Many perf issues are still JS work, reconciliation work, or browser layout/paint. |
What happens on an update
When state/props/context change, React schedules work, re-runs the affected components, builds a new tree, then reconciles it against the previous one. If it detects differences, it commits DOM mutations for only those differences.
import React from 'react';
export default function Counter() {
const [count, setCount] = React.useState(0);
// When you click:
// 1) React re-runs Counter() to compute a new element tree
// 2) Reconciliation compares old vs new children
// 3) Commit applies the minimal DOM changes (often just the text node)
return (
<button onClick={() => setCount((c) => c + 1)}>
Count: {count}
</button>
);
}
Phase | What React does | Rules / why it matters |
|---|---|---|
Render phase | Runs components to compute the next UI tree | Should be pure (no subscriptions, network calls, DOM writes). React may re-run renders (especially in dev/StrictMode). |
Reconciliation | Matches old vs new elements (type + key + position) and decides what to keep, move, mount, unmount | Keys are crucial for stable identity in lists; changing element type at a position can cause remount/state loss. |
Commit phase | Mutates the real DOM + runs effects/lifecycles | This is where DOM changes actually happen; effects run after commit. |
Keys are a big part of “VDOM performance”
Reconciliation is fast when React can match previous children to next children reliably. In lists, stable key values give identity; bad keys (like index in reordering lists) can cause unnecessary remounts, DOM churn, and state bugs.
Why React uses this model | Practical benefit |
|---|---|
Declarative UI (UI as a function of data) | You describe what the UI should be; React computes how to update it. |
Batching + scheduling | Multiple state updates can be grouped; React can prioritize urgent updates. |
Efficient updates for dynamic trees | As the UI shape changes, React can mount/unmount/move nodes without manual DOM bookkeeping. |
Tooling + predictability | The same inputs produce the same tree (when render is pure), which makes behavior easier to reason about and debug. |
Interview-quality summary
In React, “Virtual DOM” refers to the in-memory UI tree (React elements/fibers). On updates, React re-renders to produce a new tree, then runs reconciliation (diffing + keys + heuristics) to compute what changed, and finally commits only the necessary DOM mutations. A re-render is just recomputing UI — it does not automatically mean the browser DOM changed.