Using key props incorrectly in .map() operations is one of the most frequent React anti-patterns. Here’s what you need to know to fix these issues:
The Right Way to Use Keys
const items = [{id: 1, name: 'Item 1'}, {id: 2, name: 'Item 2'}];
return (
<ul>
{items.map(item => (
<li key={item.id}>{item.name}</li>
))}
</ul>
);
Common Mistakes and Fixes
1. Using Array Index as Key (Bad Practice)
// 🚫 Avoid this - problematic when list changes
{items.map((item, index) => (
<li key={index}>{item.name}</li>
))}
Why it’s bad: Indexes change when items are added/removed, causing performance issues and state bugs.
2. Missing Keys Altogether
// 🚫 React will warn you about this
{items.map(item => (
<li>{item.name}</li>
))}
Fix: Always include a key prop for list items.
3. Using Non-Stable Keys
// 🚫 Math.random() creates new keys on every render
{items.map(item => (
<li key={Math.random()}>{item.name}</li>
))}
Why it’s bad: Causes unnecessary re-renders and DOM updates.
4. Duplicate Keys
// 🚫 Will cause rendering errors if IDs aren't unique
{items.map(item => (
<li key={1}>{item.name}</li>
))}
Fix: Ensure keys are unique among siblings.
Best Practices
- Use Unique IDs from your data when available:
key={item.id}
- For non-ID data, create a composite key:
key={`${item.type}-${item.timestamp}`}
- When generating lists from strings, you can use the string itself (if unique):
{tags.map(tag => (
<span key={tag}>{tag}</span>
))}
- For nested lists, scope keys to their parent:
{categories.map(category => (
<div key={category.id}>
<h2>{category.name}</h2>
{category.items.map(item => (
<div key={`${category.id}-${item.id}`}>
{item.name}
</div>
))}
</div>
))}
Why Keys Matter
- Reconciliation: Helps React identify which items changed
- Performance: Minimizes unnecessary DOM operations
- State Preservation: Ensures component state is maintained correctly during re-renders
Special Cases
Dynamic Lists with Changing Order
For sortable/filterable lists, use truly unique identifiers rather than array positions.
Lists Without Natural Keys
If your data lacks unique IDs, consider:
- Adding IDs when fetching data
- Using a UUID library for client-side generation
- Carefully constructing composite keys from multiple fields
