Index is an anti-pattern
The problem
When mapping over data in React you sometimes see developers do that following:
{this.props.todos.map((todo, index) => (
<li key={index}>{todo}</li>
)}
At first glance, this may seem to work correctly. But if we have logic to remove an item you will notice a bug. No matter what element you remove when react re-renders the last item will be removed.
Starting:
Buy Milk
Go to movies
Learn React
Action:
Buy Milk
Go to movies -> Clicked item to remove
Learn React
Result:
Buy Milk
Go to movies
Why?
When React's diffing algorithm is called it will not look at the content of the element. So we had an array of three items with keys of 0,1,2. When one has been removed the keys become 0,1. So the React diffing algorithm only see's the difference as the last item being removed.
Starting:
<li key="1">Buy Milk</li>
<li key="2">Go to movies</li>
<li key="3">Learn React</li>
Action:
<li key="1">Buy Milk</li>
<li key="2">Go to movies</li> -> Clicked item to remove
<li key="3">Learn React</li>
Result:
<li key="1">Buy Milk</li>
<li key="2">Go to movies</li>
The Fix
Use another identifier in combination with the index to guarantee a unique key that changes when an item is removed.
{this.props.todos.map((todo, index) => (
<li key={index + todo}>{todo}</li>
)}
Starting:
<li key="1Buy Milk">Buy Milk</li>
<li key="2Go to movies">Go to movies</li>
<li key="3Learn React">Learn React</li>
Action:
<li key="1Buy Milk">Buy Milk</li>
<li key="2Go to movies">Go to movies</li> -> Clicked item to remove
<li key="3Learn React">Learn React</li>
Result:
<li key="1Buy Milk">Buy Milk</li>
<li key="2Learn React">Learn React</li>