When a list changes, position alone cannot tell a reconciliation algorithm which item survived. This matters especially for stateful components: a newly rendered virtual node does not contain the existing component instance or its state. A key gives each item an identity the algorithm can compare across updates. section 12.0 section 12.1
Removing a counter
Imagine three counters keyed `counter-0`, `counter-1`, and `counter-2`. Remove the middle one. The remaining keys tell reconciliation that `counter-2` survived and changed position; its current count cannot be inferred from the newly created virtual node. section 12.0 section 12.1
A small virtual-DOM implementation gives the key three responsibilities:
- Compare component nodes by both component definition (`tag`) and `props.key`. Two nodes of the same component type are not necessarily the same list item. section 12.1.1 section 12.1.2
- Compare element nodes by both tag and key, so reconciliation has an identity to use when elements move. section 12.2
- Remove `key` before passing props to a component or setting attributes on a DOM element. It is for reconciliation, not an ordinary component prop or DOM attribute. section 12.1.2 section 12.2
Listing 12.2 Using the key attribute to compare component nodes (nodes-equal.js)
export function areNodesEqual(nodeOne, nodeTwo) {
if (nodeOne.type !== nodeTwo.type) {
return false
}
if (nodeOne.type === DOM_TYPES.ELEMENT) {
const { tag: tagOne } = nodeOne
const { tag: tagTwo } = nodeTwo
return tagOne === tagTwo
}
if (nodeOne.type === DOM_TYPES.COMPONENT) {
const {
tag: componentOne,
props: { key: keyOne }, #1
} = nodeOne
const {
tag: componentTwo,
props: { key: keyTwo }, #2
} = nodeTwo
return componentOne === componentTwo && keyOne === keyTwo #3
}
return true
}
The component equality check is the core implementation step: it requires both matching component definitions and matching keys. section 12.1.2
Choose a key that stays with the same item for its whole lifetime and is unique among items in the same list. Different lists may reuse a key. Component lists need keys to distinguish stateful instances; element lists can render without them, but keys can avoid unnecessary reconciliation work. section 12.3.1 section 12.3.2 section 12.6
Two tempting mistakes
Do not key changing lists by array index: removing the middle counter changes the last counter’s index, making it appear to be a different item. Do not give two counters the same key: after one is removed, reconciliation cannot tell which survived. section 12.3.1 section 12.3.2


