Keys in React
If you've ever seen a warning in your console about "Each child in a list should have a unique 'key' prop," you've encountered one of React's most important concepts. Keys help React identify which items have changed, been added, or been removed.
Why Do We Need Keys?
Imagine you have a list of todo items. When you mark one as complete, React needs to update the DOM efficiently. Without keys, React would have to re-render the entire list. With keys, it knows exactly which item changed and updates only that one.
Keys help React identify which items in a list have changed, been added, or been removed. They give the elements a stable identity.
What Makes a Good Key?
- Unique: A key must be unique among its siblings (but doesn't need to be globally unique).
- Stable: The key should not change between renders.
- Predictable: The same item should always get the same key.
Good Keys vs Bad Keys
| Good Keys ✅ | Bad Keys ❌ |
|---|---|
| Database ID (user.id, product.id) | Array index (unless list is static) |
| UUID (crypto.randomUUID()) | Random numbers (Math.random()) |
| Unique combination of fields | Current timestamp |
Example: Using IDs as Keys
function UserList() { const users = [ { id: 1, name: 'John' }, { id: 2, name: 'Jane' }, { id: 3, name: 'Bob' } ];
return ( <ul> {users.map(user => ( <li key={user.id}>{user.name}</li> <!-- Good --> ))} </ul> );}The Problem with Array Index as Key
function TodoList() { const [todos, setTodos] = useState([ { text: 'Learn React' }, { text: 'Build a project' }, { text: 'Deploy app' } ]);
function deleteFirst() { setTodos(todos.slice(1)); <!-- Remove first item --> }
return ( <div> <button onClick={deleteFirst}>Delete First</button> <ul> {todos.map((todo, index) => ( <li key={index}>{todo.text}</li> <!-- Bad if list changes --> ))} </ul> </div> );}After deleting the first item, the indices shift. React might associate the wrong items with the wrong keys, causing rendering issues or bugs with component state.
When Is It OK to Use Index as Key?
- The list is static and will never change (e.g., a list of menu items).
- The list will never be reordered or filtered.
- The items have no stable IDs.
Keys and Component State
Keys are crucial when list items have their own state. If you use index as key and the list changes, React might reuse component instances with the wrong data.
function TodoItem({ todo }) { const [isEditing, setIsEditing] = useState(false); return ( <li> {isEditing ? ( <input defaultValue={todo.text} /> ) : ( <span>{todo.text}</span> )} <button onClick={() => setIsEditing(!isEditing)}> {isEditing ? 'Save' : 'Edit'} </button> </li> );}
function TodoList() { const [todos, setTodos] = useState([ { id: 1, text: 'Learn React' }, { id: 2, text: 'Build project' } ]);
return ( <ul> {todos.map(todo => ( <TodoItem key={todo.id} todo={todo} /> <!-- Stable key --> ))} </ul> );}Two Minute Drill
- Keys help React identify which items changed, were added, or removed in lists.
- Good keys are unique, stable, and predictable – usually database IDs.
- Avoid using array indices as keys if the list can change (reorder, filter, add/remove).
- Keys are crucial for performance and correct component state management.
- If you see the "missing key" warning, always fix it – don't ignore it!
Need more clarification?
Drop us an email at career@quipoinfotech.com
