Each child in a list should have a unique key prop is a React runtime warning that appears in the browser console when you render an array of elements without giving each one a stable, unique identifier.
What "Each child in a list should have a unique key prop" Means
React uses keys to track which items in a list have changed, been added, or been removed. Without a unique key, React falls back to comparing items by index, which causes incorrect DOM updates, broken state, and unpredictable behavior during re-renders. The warning is React telling you it can't reliably reconcile your list.
Why It Happens
This warning triggers when you map over an array and render JSX without providing a key prop to the top-level element returned. The most common causes are:
- You forgot to add
keyentirely when using.map(). - You used the array index as the key, which React technically accepts but warns against when the list can be reordered or filtered.
Example Code That Triggers It
Here's a minimal React component that produces the exact warning in the browser console:
import React from 'react';
interface Todo {
id: number;
text: string;
}
const todos: Todo[] = [
{ id: 1, text: 'Write docs' },
{ id: 2, text: 'Review PRs' },
];
export function TodoList() {
return (
<ul>
{todos.map((todo) => (
<li>{todo.text}</li> // ❌ No key prop — warning fires
))}
</ul>
);
}
Run this in any React app (Create React App, Vite, Next.js) and the browser console will log the warning.
How to Fix It
Add a key prop with a stable, unique value — typically an id from your data:
export function TodoList() {
return (
<ul>
{todos.map((todo) => (
<li key={todo.id}>{todo.text}</li> // ✅ Unique, stable key
))}
</ul>
);
}
The fix works because todo.id is unique per item and stays consistent across re-renders. React can now match each <li> to its corresponding data object, so state and DOM updates stay in sync even if the list order changes.
Common Mistakes That Cause This
Two mistakes I see repeatedly:
-
Using
indexas the key.key={index}silences the warning but breaks React's reconciliation. If you filter, sort, or remove items, React reuses DOM nodes incorrectly — checkboxes keep the wrong state, inputs lose focus, and animations glitch. Only use index when the list is static and never reordered. -
Putting
keyon a child instead of the mapped element. If your.map()returns a fragment or a wrapper component, the key must go on the outermost element React actually renders — not on a nested<div>inside it.
When Should You Worry About This?
You should worry when your list is dynamic — items are added, removed, reordered, or filtered at runtime. That's when missing or index-based keys cause real bugs like lost input focus, wrong checkbox states, or duplicated side effects. For a static list rendered once and never changed, the warning is harmless and you can safely ignore it.
Next time this error appears, check whether your .map() callback returns a single element with a key prop that comes from the data itself — not from index.