The Dangerous Shortcut That Every React Beginner Takes.
Why Does React Even Care About Keys?
To understand this, we have to look at how React handles the screen. React uses a Virtual DOM to keep track of what is currently visible. When your data changes, React doesn’t wipe the entire screen and redraw it from scratch — that would make your app incredibly slow.
Instead, it compares the old snapshot of your app with the new snapshot and only updates the exact HTML elements that changed.
When it comes to lists, React faces a massive puzzle. If you add an item, delete an item, or reorder the list, how does React know which specific DOM element matches which item in your JavaScript array?
It looks at the key. The key is a permanent, unique passport for that specific list.
This is What Happens When the List Shifts
If your list is completely static — meaning it never changes, never gets sorted, and never has items added or deleted — using key={index} won’t break anything.
But the moment your list becomes dynamic, the index shortcut completely fails.
Get Shreyash’s stories in your inbox
Join Medium for free to get updates from this writer.
Imagine you have a list of three tasks:
- Index 0: Buy groceries
- Index 1: Clean the room
- Index 2: Study React
You decide to delete “Buy groceries” (Index 0) from the top of the list. Here is exactly how React sees the update behind the scenes:
- React has three elements mapped to keys 0, 1, and 2.
- You delete the first item. The array now only has two items: “Clean the room” and “Study React”. Because you are using the array index as the key, “Clean the room” automatically becomes Index 0, and “Study React” becomes Index 1.
- React compares the old list with the new list. It sees that key 0 still exists (but now holds different text), key 1 still exists (with different text), and key 2 is missing.
- React thinks you simply edited the text of items 0 and 1, and deleted item 2. If item 0 had an internal state — like a checked checkbox or an active input field — that checked state stays stuck to the element at key 0. Your checkbox is now checked on the wrong task!
Because the indices changed, React mapped the old internal list state to the completely wrong data item. The text updates, but the state stays stuck to the index.
The Fix: Use Stable, Unique Identifiers
The solution to this problem is simple: Keys must be stable, predictable, and unique. They should belong directly to the data object itself, not to the array’s positioning.
Fix 1: Use Database IDs
If your data is coming from a database (like MongoDB or a public API), it almost always comes with a unique identifier like id or _id. Always default to this.
// Safe, stable, and completely predictable
items.map((item) => (
));
Even if you delete the first item, “Clean the room” keeps its exact same ID. React sees the matching ID, keeps its internal state completely intact, and accurately updates the DOM.
Fix 2: Generate Unique IDs on Creation
If you are creating items locally within your app state (like a local todo list), generate a unique ID at the exact moment the item is created, not during the render phase.
const addTodo = (text) => {
const newTodo = {
id: crypto.randomUUID(), // Generates a unique string like "de305d54-75b4-431b-adb2..."
text: text
};
setTodos([...todos, newTodo]);
};
(Note: Avoid generating random keys like key={Math.random()} directly inside your .map() function. Doing that forces React to generate brand new keys on every single render, completely wiping out component states and slowing down your app.)