Reconciliation Algorithm
Reconciliation is the process React uses to diff the previous and next virtual DOM trees and determine the minimum set of DOM mutations needed. It uses two heuristic assumptions to achieve O(n) instead of O(n³) complexity.
Reconciliation is a hotel check-in — if your name (key) is on the reservation, you get your old room (reuse fiber). If you're a different type of guest (element type changed), the whole room gets gutted and refurnished.
The two heuristics: (1) elements of different types produce entirely different trees — React tears down the old subtree and builds a new one. (2) Keys identify which children are stable across renders — without keys, React matches children by index, leading to bugs with reorderable lists. When the same component type appears in the same position, React reuses the fiber and updates props. When the type changes, the entire subtree unmounts and remounts.
For child lists, React uses a two-pass algorithm: first, it builds a map of existing children by key, then it iterates through the new list, reusing or creating fibers. This makes key-based reordering O(n). The commit phase is synchronous and uninterruptible — once React starts mutating the DOM, it finishes all mutations before yielding. This ensures the user never sees a partially updated UI. React processes effects (useEffect, useLayoutEffect, ref attachments) in a specific order during commit: all mutations first, then all layout effects, then the browser paints, then all passive effects.
Reconciliation diffs the old and new element trees using two heuristics: different element types produce different trees (tear down and rebuild), and keys identify stable children across renders. This gives O(n) complexity. React reuses fibers when the component type and position match, and tears down the subtree when they don't. The commit phase is synchronous to prevent partial UI updates.
Using array index as key in a reorderable list. When items are reordered, the key stays with the index, not the item — React reuses the wrong component instances, causing state bugs like inputs showing the wrong value.