When Index-Based Keys Aren't Just Fine. They're What You Should Use

Just a guy who loves to write code and watch anime.
Introduction
Every React tutorial tells you the same thing. "Never use array index as key." It is one of those rules people repeat without thinking about why it exists. And because they never think about why, they never learn when the rule is wrong.
The rule exists for a good reason. But there are cases where index keys are not just acceptable. They are the correct choice. Using anything else would make your app slower.
Let me show you when and why.
Why the rule exists in the first place
React uses keys to track which items in a list are which. When your list re-renders, React looks at the keys to decide what changed.
Say you have a list of messages.
["Alice", "Bob", "Charlie"]
React renders three components with keys 0, 1, 2.
Now you insert "Zara" at the beginning.
["Zara", "Alice", "Bob", "Charlie"]
With index keys, React sees this.
key=0 was "Alice", now "Zara" → re-render
key=1 was "Bob", now "Alice" → re-render
key=2 was "Charlie", now "Bob" → re-render
key=3 is new → mount
Every component re-renders. React thinks every item changed because the indexes shifted. This is wasteful. If you used unique IDs as keys, React would know that "Alice" just moved. It would reuse her component and only mount "Zara" as new.
That is the real rule. Do not use index keys when items can be reordered, inserted at the beginning, or deleted from the middle. Because the indexes shift and React loses track of which component belongs to which item.
The cases where index keys are correct
The rule breaks down when your list has a specific shape. Specifically when items are only ever appended at the end and never reordered or deleted.
Think about it. If you only add to the end, indexes never shift. Item at index 0 is always the same item. Item at index 5 is always the same item. The only thing that changes is that a new index appears at the end.
React sees stable keys for all existing items. Stable keys mean React.memo works. React.memo means skip re-render. Skip re-render means fast.
Here are the real world cases.
AI streaming markdown blocks
An AI streams text token by token. You split the markdown into blocks. Paragraphs. Headings. Code blocks.
The blocks only grow. New blocks appear at the end. Old blocks never move. Old blocks never get deleted. The last block might update its content as tokens arrive. Everything before it stays frozen.
Index keys here are perfect. Block at index 3 is always block 3. React keeps the same component instance. When the content of block 3 does not change, React.memo skips it. Zero work.
What happens if you use a content hash as key instead.
Block 3 content: "Some **bo" → key = "a1b2c3"
Block 3 content: "Some **bold" → key = "d4e5f6"
The key changed. React thinks the old component is gone and a new one appeared. It unmounts the old one. Mounts a new one. Creates new DOM nodes. Runs effects again. Loses internal state. This is the opposite of what you want. You want React to update the existing component with new props. Not throw it away and start over.
Index key keeps the component alive. Content hash key kills it and rebuilds it. Index key wins.
Chat message lists
Messages in a chat app. New messages appear at the bottom. Old messages stay where they are. Nobody reorders messages. Nobody inserts a message in the middle.
Index keys work perfectly here. Same logic as above.
Log viewers and terminal output
Lines of output that only append. New lines at the bottom. Old lines never change. Index keys are the natural fit.
Append-only tables
Data rows that only get added. Like a live feed of transactions or events. New rows at the end. Old rows stay put.
The decision framework
Ask yourself three questions.
Can items be reordered? If yes, use unique IDs.
Can items be inserted anywhere other than the end? If yes, use unique IDs.
Can items be deleted from the middle? If yes, use unique IDs.
If the answer to all three is no, index keys are not just fine. They are better. They give React stable references that make memoization work properly.
A subtle detail most people miss
There is another case where index keys break. Components with internal state.
Say each item in your list is an input field. The user types something. That text lives in the component's local state. If you delete item 2 from a list of 5 items, index keys shift. Item 3 becomes index 2. React thinks index 2 still exists and keeps its state. But now the wrong state is attached to the wrong item.
This is real and this is bad. But notice the condition. It requires deletion or reordering. If your list is append-only, this cannot happen. The state stays with the right component because the indexes never shift.
Summary
The rule "never use index keys" is a simplification. The real rule is "do not use index keys when indexes can shift." If your list is append-only, indexes are stable. Stable indexes give you better memoization than unique IDs or content hashes. In streaming and real-time append scenarios, index keys are not a shortcut. They are the right tool.






