Introduction
React frequently needs to render collections of data as lists of elements, typically by mapping an array to JSX. To efficiently update these lists, React relies on a special key prop attached to each list item. Keys help React's reconciliation algorithm identify which items have changed, been added, or been removed between renders, without keys, React falls back to less reliable positional matching, which can cause subtle bugs.
Cricket analogy: The key prop helping React identify which list items changed is like a scorer using each player's fixed jersey number rather than their current batting-order position to track substitutions correctly across innings.
Syntax
function FruitList({ fruits }) {
return (
<ul>
{fruits.map((fruit) => (
<li key={fruit.id}>{fruit.name}</li>
))}
</ul>
);
}
// fruits = [{ id: 'a1', name: 'Apple' }, { id: 'b2', name: 'Banana' }]Explanation
Each element returned from .map() must have a unique key prop among its siblings. React uses this key — not the array index by default — to match elements between renders during reconciliation. A stable, unique identifier (like a database id) is the ideal key, because it stays associated with the same logical item even if the list is reordered, filtered, or has items inserted or removed.
Cricket analogy: Using a stable database id as the key instead of array index is like tracking a bowler by their permanent player ID rather than their current bowling-order slot, so swapping the bowling order doesn't misattribute their wicket tally.
Example
function TodoList({ todos, onRemove }) {
return (
<ul>
{todos.map((todo) => (
<li key={todo.id}>
{todo.text}
<button onClick={() => onRemove(todo.id)}>Delete</button>
</li>
))}
</ul>
);
}
// Anti-pattern: using array index as key
// {todos.map((todo, index) => <li key={index}>{todo.text}</li>)}Output
When a todo is deleted from the middle of the list using its stable id as the key, React correctly removes only that specific <li> and preserves the DOM state (like input focus or CSS transitions) of the remaining items. If array index were used as the key instead, deleting a middle item would shift the indices of all subsequent items, causing React to misattribute DOM nodes and potentially preserve the wrong internal state (e.g. a text input's focus or value jumping to the wrong row).
Cricket analogy: Deleting a todo using its stable id preserves other items' state correctly, like removing a retired player from the squad list by their fixed player ID without shifting every other player's career stats to the wrong name.
Key Takeaways
- Keys let React's reconciliation algorithm match array items between renders, enabling efficient, correct updates.
- Keys must be unique among siblings but do not need to be globally unique across the whole app.
- Prefer a stable, unique identifier (e.g. a database id) as the key rather than the array index.
- Using array index as key is problematic when the list can be reordered, filtered, or have items inserted/removed, since indices shift and get reassigned to different items, causing incorrect state association and unnecessary re-renders.
- This reflects React's props-down, events-up model: the list data flows down as props, and actions like onRemove flow back up via callbacks.
Practice what you learned
1. What is the primary purpose of the key prop when rendering a list in React?
2. Which of these is generally the best choice for a key?
3. Why is using the array index as a key problematic for a reorderable or filterable list?
4. Must keys be unique across the entire application?
5. What happens if you omit the key prop entirely when rendering a list?
Was this page helpful?
You May Also Like
Props in React
Learn how props pass read-only data from parent to child components in React's one-way data flow model.
State in React
Understand how state gives components memory, enabling dynamic, interactive UIs that update over time.
Conditional Rendering in React
Learn the common patterns for showing or hiding UI elements based on conditions in React components.
React Performance Optimization
Learn how to prevent unnecessary re-renders in React using React.memo, useMemo, and useCallback.
Related Reading
Related Study Notes in Web Development
Browse all study notesWebSockets Study Notes
Web Development · 30 topics
Web DevelopmentWebAssembly Study Notes
WebAssembly · 30 topics
Web DevelopmentgRPC Study Notes
Protocol Buffers · 30 topics
Web DevelopmentSpring Boot Study Notes
Java · 30 topics
Web DevelopmentFlask Study Notes
Python · 30 topics
Web DevelopmentDjango Study Notes
Python · 30 topics