Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

React: using index as key for items in the list

Tags:

reactjs

What are the pitfalls of using an index as key for items in the list? Is there any performance pitfall for React change detection or any unexpected list update while adding or removing elements in the list as well. I have gone through several articles regarding this but still not getting it clear.

Please refer codepen

Why adding an item at the start of the list result in unexpected behavior in the above codepen?

Also, it is said that by default react passes index as a key when no key is passed. That means not passing any key and passing index as a key - both are the same thing?

like image 323
Abhinandan Khilari Avatar asked Dec 29 '19 08:12

Abhinandan Khilari


People also ask

Is it OK to use index as key React?

We don't recommend using indexes for keys if the order of items may change. This can negatively impact performance and may cause issues with component state.

Can you use index as key?

We all have heard that using index as key in a react list is an anti-pattern and should be avoided. The answer to this lies in the concepts of: React Virtual DOM: It's a lightweight representation of actual DOM, stored in memory and is never rendered.

How do you get the index of an element in a list in React?

To get the key index of an element on click in React: We used the Array. map method to render the elements in the array. We added an onClick event handler on each element.


3 Answers

this question has been asked before,

but the main answer could be found in the Docs of React

We don’t recommend using indexes for keys if the order of items may change. This can negatively impact performance and may cause issues with component state. Check out Robin Pokorny’s article for an in-depth explanation on the negative impacts of using an index as a key. If you choose not to assign an explicit key to list items then React will default to using indexes as keys.

there are no unexpected list update while adding or removing elements

but the main reason for this is the algorithm for indexing and comparing behind,

you can read about this here under 'different-types'

The key here is to understand not everything in the DOM has a representation in React "Virtual DOM" and, because direct manipulations of the DOM (like a user changing an value or a jQuery plugin listening to an element) are unnoticed by React, not using unique and constant keys will end up with React recreating the DOM node of a component when the key is not constant (and losing any untracked state in the node) or reusing a DOM node to render another component when the key is not unique (and tying its state to this other component).

Here you have a live demo showing how awful the results are

Just add an item, change it, add more items and see what happens.

have a read here too

like image 159
Dor Lugasi-Gal Avatar answered Nov 03 '22 00:11

Dor Lugasi-Gal


You are right, there can be issues with using index as key but notice I am saying we can get issues but not always. If we are not adding /removing items from list then it is fine to use index as keys else it will be good to use some id which uniquely identifies the item. Reason is if you add or remove some items from the list, indexes change for older items and react can get confused which items are changed. Performance wise i don't think it makes any difference

like image 32
Striker Avatar answered Nov 03 '22 00:11

Striker


Let's say you are rendering this array:

const data = [{
  name: 'riderOne',
  time: 10, //  let's assume it's timestamp
},{
  name: 'riderTwo',
  time: 11, //  let's assume it's timestamp
},{
  name: 'riderTwo',
  time: 12, //  let's assume it's timestamp
}];

Now let's say we have a filter with which user can choose the time taken to finish the race can be shown in 'Seconds', 'Minutes', and 'Hours'. Minutes may be the default filter. So when u just use indexes as key and try to change the filter to 'Seconds' or 'Hours', the react will look at the data and it will assume the data have not changed and will not rerender the list. Inorder to achieve that, we have use unique keys even for the filters.

key={`${item.id}-${filter}}
like image 31
k1r4n Avatar answered Nov 02 '22 23:11

k1r4n