πŸ”§ Error Fixes

React: Each Child Should Have a Unique Key Prop β€” How to Fix It


Warning: Each child in a list should have a unique "key" prop.

React needs a unique key on every element in a list so it can efficiently update the DOM when items change.

The Quick Fix

// ❌ No key
{items.map(item => <li>{item.name}</li>)}

// βœ… With key
{items.map(item => <li key={item.id}>{item.name}</li>)}

Use a unique, stable identifier from your data β€” usually an id field.

Why Keys Matter

Without keys, React re-renders the entire list when one item changes. With keys, React knows exactly which item changed and only updates that one. This matters for:

  • Performance (large lists)
  • Preserving component state (inputs, animations)
  • Correct behavior when items are reordered or deleted

Why Index as Key Is Bad

// ❌ Avoid this
{items.map((item, index) => <li key={index}>{item.name}</li>)}

Index as key breaks when you:

  • Reorder items β€” React thinks item 0 is still item 0, even though the data changed
  • Delete items β€” all items after the deleted one get wrong keys
  • Add items to the beginning β€” every item gets a new key, causing full re-render

When index is OK: Static lists that never change order and never have items added/removed. But even then, a real ID is better.

How to Pick Good Keys

Best: Use a unique ID from your data

// Database records
{users.map(user => <UserCard key={user.id} user={user} />)}

// API responses
{posts.map(post => <Post key={post.slug} post={post} />)}

If no ID exists: Generate one when creating the data

// When adding items
const newItem = { id: crypto.randomUUID(), name: "New item" };
setItems([...items, newItem]);

Don’t generate keys during render:

// ❌ New key every render = full re-mount every time
{items.map(item => <li key={Math.random()}>{item.name}</li>)}

// ❌ Same problem
{items.map(item => <li key={crypto.randomUUID()}>{item.name}</li>)}

Nested Lists

Each list needs its own keys, but keys only need to be unique among siblings:

{categories.map(cat => (
  <div key={cat.id}>
    <h2>{cat.name}</h2>
    <ul>
      {cat.items.map(item => (
        <li key={item.id}>{item.name}</li>
      ))}
    </ul>
  </div>
))}

cat.id and item.id can overlap β€” they’re in different lists.

Common Mistakes

Key on the wrong element:

// ❌ Key should be on the outermost element in the map
{items.map(item => (
  <div>
    <span key={item.id}>{item.name}</span>
  </div>
))}

// βœ… Key on the outer element
{items.map(item => (
  <div key={item.id}>
    <span>{item.name}</span>
  </div>
))}

Using non-unique values:

// ❌ Multiple users might have the same name
{users.map(user => <li key={user.name}>{user.name}</li>)}

// βœ… Use the unique ID
{users.map(user => <li key={user.id}>{user.name}</li>)}