react-key-prop
npx skills add https://github.com/flpbalada/my-opencode-config --skill react-key-prop
Agent 安装分布
Skill 文档
React: Key Prop Best Practices
Core Principle
Use stable, unique IDs from your data. Never use array index for dynamic lists.
The key prop provides stable identity to list elements during React’s reconciliation process.
When to Use What
Use Data IDs (Preferred)
Always use unique, stable identifiers directly from your data:
// â
Correct
{todos.map((todo) => (
<li key={todo.id}>{todo.text}</li>
))}
Ideal keys are:
- Unique – No two items share the same key
- Stable – Never changes during component lifetime
- Predictable – Directly tied to the data item
Generate IDs on Data Load
When data lacks IDs, create them once when receiving data:
import { nanoid } from 'nanoid';
useEffect(() => {
fetch('/api/items')
.then(res => res.json())
.then(data => {
const itemsWithIds = data.map(item => ({
...item,
_tempId: nanoid() // Stable ID generated once
}));
setItems(itemsWithIds);
});
}, []);
When Index Is Acceptable (Rare)
Index as key is acceptable ONLY when ALL conditions are met:
- List is absolutely static
- Items never added/removed (except at the end)
- Order never changes
- Items have no internal state
Anti-Patterns to Avoid
Never Generate Keys During Render
// â WRONG: Creates new key every render
{items.map(item => (
<li key={Math.random()}>{item.name}</li>
))}
This forces React to destroy and recreate all components on every render.
Don’t Use Index for Dynamic Lists
// â WRONG for dynamic lists
{items.map((item, index) => (
<li key={index}>{item.name}</li>
))}
Index fails when:
- Items are added/removed from beginning or middle
- List order changes (sorting, filtering)
- Items have internal state (like form inputs)
The bug: Index represents position, not data identity. When positions change but indexes stay the same, React incorrectly “mutates” existing components instead of creating new ones, causing state mismatch.
Don’t Use useId() for List Keys
React’s useId() hook is for accessibility (linking labels to inputs), not for generating list keys.
Quick Reference
DO
- Always use
keywhen rendering lists - Prefer unique, stable
idfrom your data - Generate IDs once at data load time (
nanoid/uuid)
DON’T
- Never generate
keyduring render (Math.random(),Date.now()) - Avoid
indexaskeyfor dynamic lists - Don’t use
useId()for list keys