What is the key prop for in React?
By FrontendPro Editorial Team Updated 9/26/2026
Answer
key tells React which item in a list is which across renders. Without it React matches children by position, so inserting, deleting, or reordering makes every item after that point look like it changed.
{todos.map(todo => <Todo key={todo.id} todo={todo} />)}
With stable keys React knows an element moved, so it reuses the existing DOM node and its state instead of rebuilding it.
Why the index is the classic bug
{todos.map((todo, i) => <Todo key={i} ... />)} // don't
Delete the first item and every remaining item's key shifts down by one. React concludes item 0's content changed rather than that item 0 was removed — so it keeps the first DOM node and rewrites the text in all of them. Anything the DOM was holding stays behind:
- Typed text in an
<input>ends up on the wrong row. - A checked checkbox stays checked next to a different label.
- Focus and scroll position land somewhere unexpected.
- Animations replay on the wrong element.
An index key is only safe when the list is static — never reordered, never filtered, nothing appended or removed, and no state or inputs inside the items.
What makes a good key
A stable, unique id from your data: a database id, a slug, a UUID created when the item was created. It must be unique among siblings only, not globally.
What not to use: the array index, Math.random() (a new key every render remounts the item every render), or an object that is recreated each render.
If your data genuinely has no id, generate one when you create the item — not at render time.
The second thing key does
Changing the key of a single component forces React to unmount and remount it, which resets all of its state. That is the idiomatic way to reset a form when the subject changes:
<ProfileForm key={userId} user={user} />
Same mechanism, used deliberately.
Details people miss
keyis consumed by React and never reaches your component as a prop. If you need the value inside, pass it twice:key={id} id={id}.- The key must be on the outermost element returned by
map, not on a child inside it. - Wrapping list items in a fragment still needs a key:
<Fragment key={id}>, since<>takes no props. - Keys are scoped to siblings, so two separate lists may reuse the same values without conflict.
