Always use stable, unique keys in array .map() renders. Missing or unstable keys (like array index) cause React to destroy and recreate DOM nodes, losing component state and causing visual glitches.
Without stable keys, React cannot track which items moved, were added, or were removed. It falls back to re-mounting components by position, which destroys local state (input values, scroll position, animation state), causes unnecessary DOM operations, and produces visible UI glitches like flickering or lost focus.
BeforeMerge scans your pull requests against this rule and 4+ others. Get actionable feedback before code ships.
React uses the key prop to identify which items in a list have changed, moved, or been removed. When keys are missing or unstable (like array indexes), React cannot efficiently reconcile the old and new lists.
The consequences are concrete: if a user is typing into an input inside a list item and the list re-orders, React will keep the input's DOM node attached to the wrong item. The user sees their text jump to a different row. Controlled inputs lose focus. Animations restart. Transitions break.
Using array indexes as keys is almost as bad as no keys at all — when items are inserted, deleted, or reordered, the indexes shift and React re-mounts components that didn't actually change.
Every element returned from .map() in JSX must have a key prop set to a value that is:
item.id, not the array indexfunction TaskList({ tasks }: { tasks: Task[] }) {
return (
<ul>
{tasks.map((task, index) => (
// BAD: using array index as key
<li key={index}>
<input defaultValue={task.title} />
<span>{task.status}</span>
</li>
))}
</ul>
);
}function TaskList({ tasks }: { tasks: Task[] }) {
return (
<ul>
{tasks.map((task) => (
// GOOD: stable, unique ID from the data
<li key={task.id}>
<input defaultValue={task.title} />
<span>{task.status}</span>
</li>
))}
</ul>
);
}Search for .map() calls in JSX that use the index parameter as key:
grep -n "key={index}" --include="*.tsx" --include="*.ts" -r src/
grep -n "key={i}" --include="*.tsx" --include="*.ts" -r src/Also look for .map() calls where no key prop is present at all — React will warn in development but the code still compiles.
key={item.id}