Reconciliation Heuristics

React reconciles a previous element tree with a new one using practical assumptions rather than computing a generally optimal tree-edit sequence. Element type and `key` are the main signals React uses to decide which existing work can be reused and which parts must be replaced.

During an update, React compares the newly produced element tree with the previous one. The goal is to determine the minimum practical set of changes needed to bring the rendered result in line with the new tree, while avoiding the cost of a general tree-editing algorithm.

A major heuristic is element type. When the element at a position changes from one type to another, React treats the old subtree as incompatible and replaces it rather than attempting to transform the old structure into the new one. When the type remains compatible, React can preserve the existing component or host-instance relationship and reconcile its children.

Lists require another signal because inserting, deleting, or reordering an item changes positions. React uses `key` values to identify corresponding siblings across renders. A stable key lets React associate an item with its previous identity even when its position changes.

These heuristics are effective because typical UI updates have structure that makes identity predictable. They are not a guarantee that React computes a globally minimal sequence of DOM or component operations. Poor keys, especially array indexes for reorderable lists, can cause state or DOM associations to follow positions rather than the intended items.

Key points

Interview questions

Why does React use reconciliation heuristics instead of a general optimal tree-diff algorithm?

A general tree-edit algorithm can be expensive for large trees because it must consider many possible transformations. React instead relies on assumptions that are common in UI trees, particularly that different element types represent different structures and that keys identify stable list items. These assumptions make updates practical without requiring a globally optimal edit sequence. The tradeoff is that developers must provide useful identity information when the structure is ambiguous.

What happens when the element type changes between renders?

React generally treats a change in element type as a change of structure rather than an update to the same instance. The old subtree is therefore not reused as though it were the same component or host element. React creates the new structure and reconciles it from there. This is one of the core assumptions that makes tree comparison efficient.

Why do React lists need keys?

A key gives React a way to recognize which sibling corresponds to which previous sibling across renders. This matters when items are inserted, removed, or reordered, because position alone may no longer identify the same logical item. With stable keys, React can preserve the appropriate component identity and state. Without suitable keys, React may make associations based on position that do not match the application's intended identity.

When is using an array index as a key risky?

An index key is risky when the list can change in ways that alter item positions. If an item is inserted or removed near the beginning, the same key can become associated with a different logical item. That can cause component state or other identity-dependent behavior to appear to move to the wrong item. Index keys are less problematic when the list is genuinely static and its ordering and membership do not change.

Does reconciliation guarantee the minimum possible DOM operations?

No. React's reconciliation strategy is heuristic rather than a general solver for the optimal tree-edit problem. It uses assumptions such as element type and keys to make decisions efficiently for common UI patterns. Those assumptions usually provide good practical behavior, but they do not imply a mathematically minimal edit sequence for every possible pair of trees.