React Mastery / React Basics

Keys

📌 What are Keys in React?

  • Keys help React identify which items have changed, been added, or removed in a list.

  • They are used internally by React during the reconciliation (diffing) process.

  • Keys must be:

    • Unique among siblings

    • Stable (should not change between renders)

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

🧠 Why Keys Are Important

React uses keys to:

  • Match previous elements with new elements

  • Decide which DOM nodes to reuse

  • Preserve component state correctly

Without proper keys:

  • React may reuse the wrong component

  • UI bugs and state issues can occur


❌ What Is “Index as Key”?

Using the array index as a key:

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

This is called an anti-pattern in most real-world cases.


🚨 Why Index as Key Is an Anti-Pattern

1️⃣ Keys Change When Items Change Order

['A', 'B', 'C']   // keys: 0, 1, 2
['A', 'C']        // keys: 0, 1
  • C gets a new key

  • React thinks it’s the same element as before key 1

  • Wrong DOM reuse happens


2️⃣ Causes State Bugs

{users.map((user, index) => (
  <Input key={index} defaultValue={user.name} />
))}

If a user is removed:

  • Input values may jump to another row

  • Component state gets mixed up


3️⃣ Breaks Animations & Transitions

  • React relies on keys to know what moved

  • Index keys make React think items were updated, not moved

  • Leads to broken or missing animations


4️⃣ Poor Performance in Updates

  • React may re-render more elements than needed

  • Loses optimization benefits of reconciliation


⚠️ When Is Index as Key Acceptable?

Using index as key is okay ONLY if all conditions are true:

✅ List is static

✅ Items are never reordered

✅ Items are never added or removed

✅ No local component state

Example (safe):

const steps = ['Start', 'Process', 'Finish'];

{steps.map((step, index) => (
  <li key={index}>{step}</li>
))}

✅ Best Practice (Recommended)

Use a stable unique ID:

{items.map(item => (
  <li key={item.id}>{item.label}</li>
))}

If no ID exists:

  • Generate one at data creation time

  • ❌ Do NOT generate keys during render (Math.random())


❌ What NOT to Do

<li key={Math.random()} />   // changes every render
<li key={Date.now()} />      // unstable

📌 Summary Table

Key Type

Stable

Safe

Recommended

Index

❌ No

❌ No

❌

Unique ID

✅ Yes

✅ Yes

✅

Random

❌ No

❌ No

❌