DEV Community

Cover image for You shouldn't use an index as key of the element
Rajnish Katharotiya
Rajnish Katharotiya

Posted on

You shouldn't use an index as key of the element

Photo by ThisisEngineering RAEng on Unsplash

Let me brief you about discussion, in React or any other stack when we need to present line of code with records of an array we use either foreach, map or for a loop. And when we do that it's good to have assigned unique key to individual component/element. As shown in an example below --

  const array = ["A", "B", "C", "D"];

  array.map((element, index) => {     // in secound parameter return current index of record
      return `<li key=${index}>       //defining key as attribute to line element
                 ${ element }
              <li>`                   //string concatination in js
  })

You can read more on the map function here.

As you have seen in snippet we have defined index in key because key have a basic rule that it should be unique and most of the developers pass index as it'll be always unique. That's correct if you are thinking that way too.

But I faced one issue recently in react development by doing it. Let me share it with you...

  • I created one react pure component (so, it won't rerender without props change) called , with height as props.
  • I used it into the map under by table component.
  • Table component:-
      const rows = [30, 60, 40, 10]         // starting point of row respective to table's starting point
      const shortedRow = shortArray(rows)   // shorting before use, value will be [10, 30, 40, 60]
      return (
          <Table>
          {shortedRow.map((row, index) => <Row height={row} key={`row-${index}`}>)}                        // tried to use string with index as well
          </Table>
          <AddRowBtn addHeightAt={35} >
      )
  • Had add row btn at below, to add new row at given height in table

The problem I was facing:

As a given scenario, on the first load of an app, it'll work like a charm. Now as I add a new row with a height of 35, it'll update my 2nd and 3rd index with a new index at the end (like [10, 30, 35, 40, 60]).

While re-rendering, since my of 3rd row's height updated but the index is the same it didn't update in DOM. And I had distributed design in output.

What I did to resolve?: ###

Instead of passing an index in key, I started to pass a value(height) in key. so as soon as the height update element will re-render without doing anything. (this is one of the advantages of it too).

Current code looks like this:

      const rows = [30, 60, 40, 10]       
      const shortedRow = shortArray(rows)
      return (
          <Table>
          {shortedRow.map((row) => <Row height={row} key={`row-${row}`}>)}                        // tried to use string with height now
          </Table>
          <AddRowBtn addHeightAt={35} >
      )

So, this was something new I figured recently. I thought to share it with you guys too. Hope this will help you, yes? then hit follow 😂.

Top comments (6)

Collapse
 
sanderdebr profile image
sanderdebr

Good article, you could also use a package like uuid() (npmjs.com/package/uuid) to generate a random unique key for you. This way you also avoid re-rendering if your amount of rows changes in this case, but it will create another dependency

Collapse
 
bytebodger profile image
Adam Nathaniel Davis

That's a dangerous pattern to follow. I've been down that path, years ago. At worst, it can spawn some nasty bugs. At best, it's needlessly inefficient.

stackoverflow.com/questions/513719...

Collapse
 
sanderdebr profile image
sanderdebr

That is interesting, I think that in your example he is generating the unique key inside the map function, which will cause re-generating the keys for every re-render. If you put the unique key outside the loop function, e.g. as an object property, it should be fine:

medium.com/@robinpokorny/index-as-...

Collapse
 
rajnishkatharotiya profile image
Rajnish Katharotiya

Solution can work, but same it will add dependency. But i think if we have any value unique in our array itself then we should just use it as key.

Collapse
 
jz222 profile image
Timo Zimmermann

There is a brilliant article on this topic on the BlackRock Engineering blog.

Collapse
 
r3wt profile image
Garrett R. Morris

This title is very misleading. Using an index is fine for most cases, but as you found, not all cases.