React Missing key Prop — List Items Warning
Fix the "Each child in a list should have a unique key" warning by assigning stable keys and understanding why index keys cause bugs.
Symptoms
- Console warns "Each child in a list should have a unique key prop"
- Reordering a list shows the wrong item state
- Input values jump to the wrong row after deletion
Possible causes
- The map callback returns elements without a key
- The key uses the array index while the list can reorder or filter
- The key is not unique, such as a duplicate id
Diagnosis steps
Locate maps without keys
grep -rn ".map(.*=>" src/ | grep -v "key="Interpretation
Every map returning JSX needs a key on the outermost element it returns.
Switch to a stable identifier
git diff src/components/List.jsxInterpretation
Using item.id instead of index fixes the state mix-up on reorder and delete.
Root cause
React uses keys to match elements between renders. Without keys, or with index keys on a reorderable list, React cannot tell which item moved, so it reuses the wrong DOM and state.
Fix
Give each rendered item a stable, unique key from the data (an id or slug), never the array index when the list can change order or length.
Risk note
Random keys force remounts every render, destroying state and performance; keys must be stable across renders.
Verify the fix
Reorder and delete items and confirm each row keeps its own state; the console warning should be gone.
Symptoms
When you hit “React Missing key Prop — List Items Warning”, guessing wastes time. The guide below follows evidence: reproduce the symptom, run targeted diagnostics, identify the root cause, apply the fix, and verify it with concrete checks.
Observed symptoms include:
- Console warns “Each child in a list should have a unique key prop”
- Reordering a list shows the wrong item state
- Input values jump to the wrong row after deletion
Reproduce and Diagnose
Reproduce the failure in isolation before changing any code. Work through the checks below in order; each one narrows the search space.
Step 1: Locate maps without keys
grep -rn ".map(.*=>" src/ | grep -v "key="
Every map returning JSX needs a key on the outermost element it returns.
Step 2: Switch to a stable identifier
git diff src/components/List.jsx
Using item.id instead of index fixes the state mix-up on reorder and delete.
Likely contributors, in order of frequency:
- The map callback returns elements without a key
- The key uses the array index while the list can reorder or filter
- The key is not unique, such as a duplicate id
Root Cause
React uses keys to match elements between renders. Without keys, or with index keys on a reorderable list, React cannot tell which item moved, so it reuses the wrong DOM and state.
The Fix
Give each rendered item a stable, unique key from the data (an id or slug), never the array index when the list can change order or length.
Watch out: Random keys force remounts every render, destroying state and performance; keys must be stable across renders.
function TodoList({ todos }) {
return (
<ul>
{todos.map((t) => (
<li key={t.id}>{t.text}</li> // stable id, not index
))}
</ul>
);
}
// ❌ key={index} breaks state on reorder/delete
Verify and Prevent
Reorder and delete items and confirm each row keeps its own state; the console warning should be gone.
Once verified, add a regression test that reproduces the original symptom so the failure cannot silently return.
This class of failure is usually environmental rather than pure logic, so capture the exact command, the environment variables, and the working directory in your bug report. Reproduce it in the smallest possible script, then widen the scope only once the minimal case is understood. A short written checklist for this failure mode saves hours the next time it appears.