Why Do We Need to Add Keys When Rendering Lists in React?

February 14, 2023

☕️ Support Us
Your support will help us to continue to provide quality content.👉 Buy Me a Coffee

In React, when rendering a list, adding a unique key prop to each element is essential. Otherwise, a Warning: Each child in a list should have a unique key prop. error message will be displayed. But why is adding keys so important, and what principles should we follow when using them? Understanding this concept is crucial when developing in React and is a fundamental question that is often asked in interviews.

Why DO We Need to Add Keys When Rendering Lists in React?

In React, key is like a unique identifier that allows React to differentiate which child components have been added, removed, or modified. (Editor's note: To further explain this concept, it is recommended to refer to Dan Abramov's tweet example) in an interview.)

React key example

From the linked example, it can be seen that when the three circles of red, yellow, and blue become red, blue, and yellow, there are two possibilities. Possibility one is that the second and third circles have swapped positions, and possibility two is that the second circle has become blue and the third circle has become yellow. Without a unique identifier, we would not know which possibility it is.

Without effective identification, bugs may occur. For example, if the circles have states, such as checkboxes inside them, and the second circle is checked, if the color change is due to the second circle being moved to the third position, in the new rendering, the third circle should be checked. However, if we do not have an identification mechanism, if React mistakenly assumes that the color change is not due to the position change but simply the color change of the second circle, then it will render that the second circle is still checked, which will be a bug.

However, with the key identification mechanism, React knows which component should preserve the original state in the list during a new rendering. Therefore, the reason why React needs keys is that they allow React to differentiate which child components have been added, removed, or modified.

In addition to that, there is an example in the React official documentation (Editor's note: this is also a recommended example for interviews). In the example, there is a list, and we add a new item to the top:

<li>Connecticut</li>

If there were no keys, for React, it would be as if Duke became Connecticut, Villanova became Duke, and a new Villanova was added at the end. In other words, the entire list has changed, so React will discard the old one and rebuild a new list. This is very performance-intensive when the list becomes large.

// Original
<ul>
  <li>Duke</li>
  <li>Villanova</li>
</ul>

// After the change
<ul>
  <li>Connecticut</li>
  <li>Duke</li>
  <li>Villanova</li>
</ul>

However, if we add keys 2015, 2016 to the list items, React will discover that 2015 and 2016 have not changed, so it will leave them untouched. It will only add

<li key="2014">Connecticut</li>

to the top. This approach is much more efficient than discarding the entire list and rebuilding it.

// Original
<ul>
  <li key="2015">Duke</li>
  <li key="2016">Villanova</li>
</ul>

// After the change
<ul>
  <li key="2014">Connecticut</li>
  <li key="2015">Duke</li>
  <li key="2016">Villanova</li>
</ul>

In summary, keys allow React to differentiate which child components have been added, removed, or modified. This not only helps to prevent some bugs related to state changes but also makes the rendering process more efficient during updates.

Follow-Up Question: What Principles Should Be Followed When Using Keys?

Keys Must Be Unique

As previously mentioned, keys are a mechanism for React to identify child components in a list, and therefore keys must be unique to avoid potential bugs.

Keys Need To Be Stable and Predictable, or Performance May Degrade

For example,

key={Math.random()};

cannot be used. The reason why random values cannot be used is that when React encounters a key, it compares the original nodes based on the algorithm of the rendering mechanism. If it finds that the keys are different, React will destroy the old node and create a new one. If the node hasn't changed at all and is only destroyed and rebuilt because of the difference in keys, this will cause unnecessary rebuilds and reduce performance (Editor's note: For more information, refer to this React official document).

Avoid Using Index as Key

In fact, if you don't specifically set a key, React defaults to using the index of the list as the key. If the list does not have any order changes, such as the three circles above not changing position but only their colors, then there will be no problem. However, using index as the key may cause bugs when the order changes.

For example, if we have a list like the one below and we add an item at index 1, it will cause the original index 1 to become 2. If the item at index 1 had some state, such as Duke being checked, it will now be Boston being checked, while Duke is unchecked. This is the bug we want to avoid!

// Before inserting new item
<ul>
  <li key="0">Connecticut</li>
  <li key="1">Duke</li>
  <li key="2">Villanova</li>
</ul>

// After inserting new item
<ul>
  <li key="0">Connecticut</li>
	<li key="1">Boston</li>
  <li key="2">Duke</li>
  <li key="3">Villanova</li>
</ul>

In summary, the key needs to be unique, stable and predictable, and avoid using the index as the key. These are the three things we need to avoid when using keys.

☕️ Support Us
Your support will help us to continue to provide quality content.👉 Buy Me a Coffee