zishu's blog

zishu's blog

一个热爱生活的博主。https://zishu.me

Why is the key required?

Previously, it was mentioned that when rendering lists in React, each data item should be assigned a key value to provide a unique identifier. The method of assigning a key was also described in detail. Now, why do we need to do this?

How to render lists in React?

By default, when recursively traversing the child elements of a DOM node, React simultaneously traverses the lists of both child elements. When differences occur, a mutation is generated.

When adding elements to the end of the child element list, the update cost is relatively small. For example:

<ul>
  <li>first</li>
  <li>second</li>
</ul>

<ul>
  <li>first</li>
  <li>second</li>
  <li>third</li>
</ul>

React will first match the trees corresponding to the two <li>first</li> elements, then match the tree corresponding to the second element <li>second</li>, and finally insert the tree of the third element <li>third</li>.

If you simply insert the new element at the beginning of the list, the update cost will be relatively high. For example:

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

<ul>
  <li>Connecticut</li>
  <li>Duke</li>
  <li>Villanova</li>
</ul>

React will not realize that it should keep <li>Duke</li> and <li>Villanova</li>, but will rebuild each child element. This situation can cause performance issues.

key

To solve the above problem, React supports the key attribute. When the child element has a key, React uses the key to match the child elements in the original tree and the latest tree. The following example makes the previous inefficient transformation efficient by adding a key:

<ul>
  <li key="1">Duke</li>
  <li key="2">Villanova</li>
</ul>

<ul>
  <li key="0">Connecticut</li>
  <li key="1">Duke</li>
  <li key="2">Villanova</li>
</ul>

Now React knows that only the element with the key '0' is a new element, and the elements with the keys '1' and '2' have only been moved.

In real scenarios, generating a key is not difficult. The element you want to display may already have a unique ID, so the key can be directly extracted from your data:

<li key={item.id}>{item.name}</li>

When the above situation does not apply, you can add an ID field to your model or use a part of the content as a hash value to generate a key. This key does not need to be globally unique, but it needs to be unique within the list.

Finally, you can also use the index of the element in the array as the key. This strategy is suitable when the elements are not re-ordered. If there are order modifications, the diff process will become slow.

When reordering components based on the index, the component state may encounter some issues. Since the component instances are determined by their keys for updating and reusing, if the key is an index, modifying the order will modify the current key, which may result in unexpected changes in the state of uncontrolled components (such as input boxes).

Loading...
Ownership of this post data is guaranteed by blockchain and smart contracts to the creator alone.