A key is not a warning-silencer
When React compares a previous list with a new list, it uses a key to decide which child is the same conceptual item. That identity determines whether local state, focused DOM nodes, and effects are preserved or discarded.
Without stable keys, React falls back to position. Position is only identity when the list never inserts, removes, filters, or reorders.
// Fragile when rows can move
items.map((item, index) => <Row key={index} item={item} />)
// Stable identity from the data model
items.map(item => <Row key={item.id} item={item} />)The editable-list failure
Imagine each Row has its own input state. Type in the second row, then insert a new row at the top. With index keys, React reuses the old second Row instance for the new second position. The text appears to jump to a different item because its state followed the position, not the record.
The same pattern produces wrong expanded accordions, stuck checkbox values, and misleading animations.
Keys decide reset versus preservation
A different key intentionally asks React for a new instance. This is useful when changing a profile should clear an unsaved form, or switching a quiz question should reset its timer. It is more explicit and reliable than writing an effect just to manually reset several state variables.
function ProfilePage({ userId }: { userId: string }) {
return <ProfileEditor key={userId} userId={userId} />;
}Where stable ids come from
Use the database id whenever possible. For a newly created optimistic record, generate a client id once when the record is created and keep it when the server response arrives. Never generate a fresh random key while rendering: that tells React every row is brand new on every render.
- Good: database ids, stable slugs, persisted client ids.
- Sometimes acceptable: index in a truly static list.
- Bad: Math.random(), Date.now(), and an object created during render.
Key Takeaways
- Keys represent conceptual identity, not visual position.
- Index keys fail as soon as list order can change.
- Changing a key is a precise, intentional way to reset a component subtree.
Ready to explain this under interview pressure?
Learn the mental models, then practise applying them to realistic frontend problems.
Join Cohort 3 Waitlist