Skip to content
C Codeloom
React

The React key Prop: A Deep Dive Into Identity and Reconciliation

Understand what the React key prop actually does, how it drives reconciliation, and why a bad key choice causes mysterious state and animation bugs.

·4 min read · By Codeloom
Intermediate 9 min read

What you'll learn

  • What the key prop tells React
  • How reconciliation uses keys to match nodes
  • Why index keys often cause bugs
  • How to force a remount with a key change
  • When to derive keys vs accept array index

Prerequisites

  • Comfortable with JS and HTML
  • Basic React component knowledge

What and Why

Almost every React developer has hit the warning “Each child in a list should have a unique key prop.” Many add a key, see the warning go away, and move on. But the key prop is one of the most powerful tools React gives you. It controls component identity, which in turn controls state preservation, animations, and even effect re-runs.

A key is React’s way of saying, “this element here is the same element that was here last render.” Without that hint, React has to guess by position, which is often wrong.

Mental Model

When React re-renders a list, it has to decide for each item: is this new, removed, or just moved? If items have keys, React matches old and new children by key. Same key means same identity, so React reuses the existing DOM node and the component’s state. A new key means a brand new component, with a fresh mount and fresh state.

Think of keys as social security numbers for components. Reorder a class roster and the students keep their grades because their IDs stay the same. Give two students the same ID and the grades get mixed up. Issue a new ID to an existing student and they look like a new person.

Old: [A:k1] [B:k2] [C:k3]
New: [C:k3] [A:k1] [B:k2]

React sees same keys -> reuses nodes and state -> just reorders DOM.

vs. using index keys:
Old at index 0 = A, new at index 0 = C
React thinks A turned into C -> wrong state preserved.
How React matches list children by key

Hands-on Example

Consider a todo list where each item has its own input for inline editing:

function TodoList({ todos }) {
  return todos.map((todo, i) => (
    <TodoItem key={i} todo={todo} />
  ));
}

This looks fine until the user deletes the first item. React sees the same indices but different data and tries to reuse components. The local edit state from the deleted item now appears on what was the second item. To users, it looks like their text leapt to the wrong row.

The fix is to use a stable, unique key derived from the data:

todos.map((todo) => <TodoItem key={todo.id} todo={todo} />);

Now React correctly identifies each item across renders. State stays with the right todo.

Keys also let you force a remount on purpose. Suppose you want a form to reset whenever the selected user changes:

<UserForm key={selectedUserId} user={user} />

Changing selectedUserId gives the form a new key, so React unmounts the old one and mounts a fresh one. All internal state, refs, and effects reset. This is much cleaner than manually clearing every field.

Common Pitfalls

Using array index as the key is the most common source of subtle bugs. It works fine for static lists but breaks the moment items can be added, removed, or reordered.

Random keys like Math.random() or crypto.randomUUID() inside render are worse. Every render produces new keys, so React thinks every item is new and remounts everything. Inputs lose focus, animations restart, effects re-run.

Watch out for keys that are not unique. Two siblings with the same key produces undefined behavior and a console warning. This often happens when joining data from multiple sources.

Finally, do not put the key on a wrapper inside the mapped component. The key belongs on the outermost element returned by the map callback, the one React actually puts into the list.

Best Practices

  • Use stable IDs from your data whenever possible.
  • Reach for index keys only when the list is static and order never changes.
  • Use a deliberate key change to remount a component instead of writing reset logic.
  • Generate IDs once when items are created, then store them, rather than computing per render.
  • Audit list rendering when you see inputs losing focus or state appearing on the wrong row.

Wrap-up

The key prop is not just a way to silence a warning. It is React’s identity system for siblings. Stable, unique keys keep state attached to the right item, preserve focus, and let animations behave. Misused keys produce some of the most confusing bugs in React. Once you internalize that keys are identity, you stop guessing and start designing your lists with intent.