Why we can’t use index as key for React list items

ref – http://chineseruleof8.com/code/index.php/2020/06/29/why-we-must-bind-prototype-functions-for-event-handlers-in-react/

source code


create-react-app index-list-example
cd index-list-example
npm start

Go your App.js and change the functional component into a class component.
1) add ‘class App extends React.Component’
2) add constructor
3) add a render prototype function

We then add a state property called list. It’s an array to simply display our list of data.
We put code to map through this list in function render:

Displaying Item data

Now, let’s write a function called Item that will display each item in the list.
As a function component, it takes the prop as a parameter. We use this prop to get each item from the list.
Then display the properties name/id from each item and display it.

then use this Item component in render:

Add items to the list

First, let’s create a button. Remember that standalone functions (due to being referenced in global environment and being run in strict mode), will dynamically
(http://chineseruleof8.com/code/index.php/2020/06/29/why-we-must-bind-prototype-functions-for-event-handlers-in-react/)
set ‘this’ to undefined, we must bind it correctly.

Then in render, we put a button and handler there:

Run it

First, write your name at the top. Then click the button to add items.

When you first write the name ‘ted’, and assigns the index to the key of that component, React will think that ‘ted’ should always appear at index 0.

Thus, as you keep adding items, ted stays at index 0.

However, say we add item to front of the list

Make this code change in prototype function addItem:

Now run it again. We put Mike at the box with timestamp of …940:

However, when we append more items to the front of the list, the name Mike gets displayed erroneously index 0, instead of the correct textfield at …940.

This happens because we erroneously assigned array index to our key. As each Items appear, React will assign different index each time these items are rendered. For example, the first time item1 appears, it gets 0. We append item2 on top, so item2 gets 0, item1 gets 1. See? Their keys have changed. ‘mike’ always gets assigned to key 0, and thus, when item2 appears, it appears in item2, instead of item1.

Solution

The solution to this is to use a unique id as key. Notice when we assigned timestamp to our object’s name, we also assign it to id. Timestamp is unique so every entry will be different. This means every entry’s key will be unique. Thus when they get rendered, their respective data will always be matched to the Component Item’s key. Thus, if we were to put ‘ricky’ at an Item1, no matter what kind of Items get appended at anywhere, React will also look for the Component that has the key with the unique ID to insert ‘ricky’ in.

Full Source