๐Ÿณ IntuitiveFE
Login
โ† All concepts

Reconciliation & the Role of Keys

โฑ๏ธ ~3-minute bite ยท solve the sandbox to master

0%lesson
๐Ÿง’

5-Year-Old Metaphor

โ€” The physical, real-world picture. No jargon.

๐Ÿชช Keys are ID cards in a lineup. Without IDs, detective compares everyone by position (may misidentify). With IDs, detective instantly knows who moved, who's new, who left.

No keys โ€” position-based

React compares items by their position in the list. Remove item 0 โ†’ React thinks items 1 and 2 changed. Updates 2 nodes unnecessarily. State may get misassigned.

With keys โ€” identity-based

React tracks each element by its key. Remove key=a โ†’ 1 removal. Reorder โ†’ React moves DOM nodes. State follows the key, not the position.

React's diffing heuristics (O(n) not O(nยณ))

React's reconciler makes two assumptions: (1) Elements of different types produce different trees โ€” no diffing across type changes, just destroy and remount. (2) Keys hint that elements are stable across renders. These assumptions allow O(n) diffing instead of the theoretically optimal O(nยณ) tree edit distance algorithm.

๐ŸŽ›๏ธ

Interactive Sandbox

โ€” Move something, see it react instantly.

Pattern

Before

[A, B, C]

After

[B, C]

DOM Operations

Update node 1: A โ†’ B

Update node 2: B โ†’ C

Remove node 3

React compares by position. Can't tell A was removed. Updates 2 nodes that didn't change, removes 1 extra.

1 / 2
Gotcha: Without keys, React may preserve the wrong DOM node's state. An input with text may keep its value even after the item it was in was removed โ€” because React reused the DOM node for a different item.
Insight: React's diffing heuristic: same type + same position = same element. Different type = destroy + remount. This works well for static lists; it fails for dynamic lists where items can move.
Explored:๐Ÿšซโœ…๐Ÿ”„โš ๏ธ๐Ÿ”‘
๐ŸŽฏ

Challenge

Step through all scenarios for each pattern. Understand which DOM operations React performs.

Try it
๐ŸŽฏ

Why Should I Care?

โ€” The exact interview question + the bug it kills.

Interview questions

Q: What heuristic does React use for reconciliation without keys?

Same component type at the same position = same element (update it). Different type at the same position = destroy and remount. React walks the tree comparing old and new virtual DOM node by node. Without keys, list items are identified by their index in the parent array.

Q: When is using the index as a key acceptable?

Only when three conditions are ALL true: (1) The list is static โ€” items never reorder, filter, or delete. (2) Items have no associated stateful UI (no inputs, checkboxes, or expandable sections). (3) The list is not re-ordered from outside React. In practice, almost never โ€” if there's any chance the list will change, use stable IDs.

Q: How do keys cause component remounting?

js
1// React uses key + type to identify an element
2// If EITHER changes, React unmounts the old and mounts a new one
3ย 
4// Same key, same type โ†’ update (efficient)
5<Input key="name" value={nameValue} /> // render 1
6<Input key="name" value={newValue} /> // render 2 โ†’ UPDATE
7ย 
8// Different key, same type โ†’ unmount + mount (full reset)
9<Input key="user-1" /> // render 1
10<Input key="user-2" /> // render 2 โ†’ UNMOUNT + MOUNT
11ย 
12// This is intentional: use to reset form between users
13<ProfileForm key={userId} /> // changes user โ†’ fresh form
๐Ÿ”ฌ

The Deep Dive

โ€” Spec refs, engine internals, the minutiae.

React Fiber reconciliation algorithm

React's reconciler (Fiber) walks the component tree comparing old and new fibers. For each fiber, it checks: same type? same key? If yes โ€” update (reuse the existing DOM node, apply new props). If no โ€” unmount old, mount new. This walk is interruptible in Concurrent Mode โ€” high-priority work can interrupt and resume it later.

Fragments with keys

js
1// Fragment with key โ€” useful for keyed groups
2function DefinitionList({ terms }) {
3 return (
4 <dl>
5 {terms.map((term) => (
6 // Key on Fragment, not on dt or dd
7 <React.Fragment key={term.id}>
8 <dt>{term.name}</dt>
9 <dd>{term.definition}</dd>
10 </React.Fragment>
11 ))}
12 </dl>
13 );
14}
15// <> shorthand doesn't support key โ€” must use React.Fragment

Performance implications of bad keys

Wrong keys (index, random) cause React to discard and recreate DOM nodes on every render. For large lists (100+ items), this means 100+ DOM node creations per interaction instead of 0-5. The DOM is expensive โ€” node creation, style computation, layout โ€” all happen again. Proper keys reduce DOM mutations to the minimum required by the actual data change.

๐ŸŽค

Interview Questions

โ€” Real questions from real interviews โ€” with answers.

Two rules: different element types produce different trees (destroy + remount); keys identify stable elements across renders.

Index keys cause React to reuse DOM nodes for wrong items when the list reorders or shrinks โ€” especially corrupting uncontrolled input state.

React identifies elements by type + key; when the key changes, React unmounts the old and mounts a fresh component.

Only for truly static lists that never reorder, filter, delete, and contain no stateful UI.

Every render generates a new key for every item โ€” React destroys and recreates all DOM nodes on every render.

Fiber reconciles in units of work that can be paused; keys are resolved during the reconcile phase and remain stable through interruption.

๐ŸŽฎ

Memory Game

โ€” Quick quiz โ€” lock the concept in long-term memory.
1/4

A developer generates keys using a counter that resets to 0 every re-render. What bug does this introduce?