jmalvarez.dev
Menu

How does the React "key" prop work?

Author's avatar
José Miguel Álvarez VañóJuly 16, 2022

Why is the "key" prop needed?

The key prop is the only thing React can use to identify components in the DOM when they are mapped from an array. If no key is provided then you will see an error like the following one:

Missing "key" prop for element in iterator

In that case, React will default to use the index of the element in the array as the key. Usually, developers will also provide index as the key just to remove the warning.

Using the index as the key is dangerous and can lead to bugs as stated in the official React docs:

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.

Why using the index as key is wrong?

The problem comes when adding, removing or modifying elements in the array. I've prepared a small component to see the effect of using the index as key.

We have the following array:

[
  {
    "text": "Item A"
  },
  {
    "text": "Item B"
  },
  {
    "text": "Item C"
  }
]

And we are mapping it to React components using the index as the key.

items.map((item, index) => (
  <div key={index}>
    <label>
      Index {index} - {item.text}
      <input type="text" />
    </label>
    <button onClick={removeElement}>Remove</button>
  </div>
));

React will identify each component with the index provided. For example, the item A is identified with index 0.

Now try to type some text in each input of the live example below. React will store the state for each element. After typing something in all three, remove the first component.

What happened?

The first element was removed from the array as we can see and then the second element was identified with index 0. Because of this, React thinks that the first element was not removed because index 0 is still present and the state of the first element is now stored in the second element.

What React sees is that the element identified with index 3 no longer exists and the state of that element was lost.

How to fix it?

The solution is to use a stable unique id as the key. React will always identify the element correctly this way.

We've now provided a unique ID to each element in the array.

[
  {
    "id": "item-a",
    "text": "Item A"
  },
  {
    "id": "item-b",
    "text": "Item B"
  },
  {
    "id": "item-c",
    "text": "Item C"
  }
]

And we are using it as the key.

items.map((item, index) => (
  <div key={item.id}>
    <label>
      Index {index} - {item.text}
      <input type="text" />
    </label>
    <button onClick={removeElement}>Remove</button>
  </div>
));

Reproduce the same steps in the next live example. See how now React correctly handles the modification of the array.

Conclusion

Resources

José Miguel Álvarez Vañó
© 2022
jmalvarez.dev