React reconciliation
Understand identity, keys, render trees, and state preservation.

WHAT YOU WILL BE ABLE TO DO
Learning outcomes
- Explain react reconciliation in plain language.
- Connect the behavior to the underlying browser or framework model.
- Implement the core pattern and reason through edge cases.
- Answer common follow-ups without relying on memorized phrases.
01Render trees
Every render produces a tree of React elements. Reconciliation diffs that tree against the previous one to compute the minimal set of DOM mutations, instead of rebuilding the DOM from scratch.
02Identity
An element's identity is determined by its type and its position (or explicit key) among siblings. Same type at the same identity: the existing instance and its state are reused. Different type, or a different key: the old instance is unmounted and a new one is mounted.
03Keys
- Use a stable, unique-among-siblings identifier — never the array index for lists that can reorder, insert, or delete.
- A changing key is a deliberate reset tool: it forces React to unmount and remount, clearing state on purpose.
- Keys only need to be unique among siblings, not globally.
{items.map((item) => ( <Row key={item.id} item={item} />))}04Fiber
Fiber is the reconciler's internal data structure and work loop: each fiber node represents a unit of work, letting React pause, prioritize, and resume rendering instead of blocking the main thread with one giant recursive pass.
DDConcept deep dives
Deep dive 1
Render calculates; commit changes the host
A React update first renders components to calculate the next element tree. React may pause, repeat, or discard this work, so render must remain pure. Reconciliation compares identities and determines required changes. During commit, React applies DOM mutations, updates refs, and runs commit-phase effects against one consistent result.
- A component render does not imply a DOM mutation.
- Side effects during render can leak from work React never commits.
- Use the Profiler to distinguish render cost from browser layout and paint cost.
Deep dive 2
Type, position, and key define identity
React preserves state when it can match the same component identity at the same logical position. Changing an element type replaces the subtree. Within sibling lists, keys extend identity beyond physical position so records can move without exchanging local state. Changing a key deliberately resets a subtree and its uncontrolled state.
- Keys need stability among siblings, not global uniqueness.
- A record id is usually stable; a generated value during render is not.
- Index keys are safe only when membership and order truly never change.
{rows.map((row) => ( <EditableRow key={row.id} row={row} />))}
// Deliberate reset when the selected record changes<Editor key={selectedId} record={selected} />The row id lets state follow its record through reordering. The editor key intentionally treats each selected record as a fresh editing identity.
Deep dive 3
Memoization changes work, not meaning
React.memo can skip a component render when props compare equal, and useMemo or useCallback can stabilize selected values. These optimizations are useful only where avoided work exceeds their comparison and complexity cost. Context changes and local state still update consumers, while one always-new object can defeat an entire memo boundary.
- Measure a slow interaction before adding memoization.
- Narrow state ownership often removes more work than wrapping descendants.
- Correctness must not depend on a memoized value being retained forever.
QAInterview questions and model answers
Attempt each answer aloud before opening it. The model answer shows the depth and precision expected in an interview; it is not a script to memorize.
Intermediate · Conceptual · 1 min · Question 1What is React reconciliation?Open model answer
Model answer
Reconciliation is the process React uses to compare the element tree produced by a render with the previous tree and determine which host updates are needed. Rendering computes the desired UI; committing applies changes and runs commit-phase work. A component rendering does not automatically mean its DOM node changes.
Open question page →Intermediate · Coding · 1 min · Question 2How does React decide whether component state is preserved?Open model answer
Model answer
State is associated with a component's position and identity in the render tree. If the element type and key at a position remain compatible, React preserves state. Changing the type or key tells React that it is a different identity and resets that subtree.
{show ? <Panel /> : <Panel />} // same type + position -> state kept{show ? <PanelA /> : <PanelB />} // different type -> unmount + remount<Panel key={userId} /> // key change -> state reset on purposeIntermediate · Coding · 1 min · Question 3Why are stable keys important in a list?Open model answer
Model answer
Keys let React match siblings across insertions, removals, and reordering. A stable key should represent the underlying entity. An array index represents a position, so using it for reorderable stateful rows can move state and DOM association to the wrong item.
// Bad: index changes meaning when the list reorders{rows.map((row, i) => <Row key={i} row={row} />)}
// Good: identity follows the record{rows.map((row) => <Row key={row.id} row={row} />)}Intermediate · Conceptual · 1 min · Question 4Does React compare the entire DOM after every state update?Open model answer
Model answer
No. React invokes the relevant component work to produce elements, reconciles those elements, and commits only necessary host mutations. The exact scheduling and bailout behavior depend on component boundaries, priorities, and memoization.
Open question page →Intermediate · Coding · 1 min · Question 5What does React.memo guarantee?Open model answer
Model answer
It can skip rendering when props are shallowly equal, but it is a performance optimization, not a semantic guarantee. Internal state and consumed context can still trigger rendering, and unstable object or function props defeat shallow equality.
const Row = React.memo(function Row({ row }) { /* ... */ });
// Defeats memo — new object identity every parent render:<Row row={{ ...row }} onSelect={() => select(row.id)} />
// Helps memo — stable references:<Row row={row} onSelect={onSelect} />Advanced · Conceptual · 1 min · Question 6What is Fiber?Open model answer
Model answer
Fiber is React's internal unit-of-work representation and reconciliation architecture. It lets React split, prioritize, pause, resume, and discard render work before commit. The important interview distinction is that render work may be interruptible while commit work applies a consistent result.
Open question page →Intermediate · Conceptual · 1 min · Question 7What happens when an element type changes at the same position?Open model answer
Model answer
React replaces that subtree, removes its prior host nodes and state, and mounts the new type. Compatible-looking output does not preserve component identity.
Open question page →Beginner · Conceptual · 1 min · Question 8Can keys be read through component props?Open model answer
Model answer
No. key is reserved reconciliation metadata and is not delivered as a normal prop. Pass a separate id prop when the component needs the value.
Open question page →Advanced · Conceptual · 1 min · Question 9Why can defining a component inside another component reset state?Open model answer
Model answer
A new component function identity is created on every outer render, so React sees a different element type and remounts the nested subtree.
Open question page →Advanced · Conceptual · 1 min · Question 10What does batching change?Open model answer
Model answer
React groups eligible state updates before rendering, reducing intermediate work. Each render still receives a consistent snapshot, and functional updaters compose queued changes.
Open question page →SCScenario questions
Scenario 1
Editable rows show the wrong draft after the list is sorted. Each row uses its array index as key.
- Identify that indexes describe positions rather than records.
- Trace how state is preserved at the same keyed position after sorting.
- Use a stable record id for identity.
- Decide whether drafts belong locally or in a normalized parent store.
Reveal worked answer
After sorting, index 0 may represent a different record, but React preserves the state associated with key 0. A stable record id makes state follow the record. If drafts must survive filtering or virtualization, I would also consider storing them by record id outside the row.