Inside React's key: where it lives and how reconciliation actually uses it
Misunderstanding React's key leads to subtle state and DOM bugs in lists, especially with inputs, animations, or reorderable data. Knowing that key is stored on the Fiber and that React compares key and type lets you pick stable identifiers and predict exactly when components will be reused or recreated.
React's key lives on the ReactElement and then on the Fiber, never on the actual DOM node or in props. When a list renders, React uses key to match old and new nodes during reconciliation: first compare key, then type. If both match, the old Fiber is reused and state is preserved. If the key matches but the type differs, React recreates the node and deletes the old one.
Multi-node reconciliation runs in three phases: a left-to-right scan that stops at the first key mismatch, a check for whether either side is exhausted, and a Map-based fallback for remaining nodes. The `lastPlacedIndex` heuristic decides which nodes need moving, but it does not guarantee minimal moves: reordering A B C D to D A B C marks A, B, and C as moves instead of just moving D.
For choosing keys, stable business IDs beat array indices. Because an absent key becomes null (not the index), React falls back to positional matching, which can couple a component's state to a slot rather than to the data. Composite keys like `${tenantId}:${id}` solve collisions when IDs are only unique within a scope. Index is acceptable only for static, fixed-order lists where the data-to-position correspondence never changes.
React's left-to-right scan and lastPlacedIndex heuristic are pragmatic but not optimal; the D A B C example shows React moving three nodes when moving one would suffice, so developers should not assume React minimizes DOM moves.
Because key becomes null when absent, React's Map fallback uses index as the map key, which is why index-as-key works for stable lists but silently couples component state to list position in dynamic lists.
The article's emphasis on type matching after key means a unique key alone does not guarantee reuse; changing component type at the same key forces recreation, which is a common gotcha for developers who swap components without changing keys.