Correct Usage of key in react

  Front end, javascript, react.js

image

When developing react programs, we often encounter such warnings, and then we think: Oh! Loop subcomponent forgot to add key ~

For convenience, we sometimes use the circular index as the key without thinking, but is this really good? What is the best value for key?

In order to understand, this article will analyze “key” from three aspects:

1. why use key

2. Problems Existing in Using index as key

3. Choose key correctly

1. why use key

React official documents describe key as follows:

Keys can help React identify which elements have changed when some elements in DOM are added or deleted. Therefore, you should give each element in the array a definite identifier.

React’s diff algorithm uses the key as the unique id and then compares the value of the component to determine whether it needs to be updated, so react will not know how to update the component without the key.

You can also use the key if you do not pass it because react will use the index of the array as the key by default after detecting that the sub-component does not have the key.

React decides whether to destroy the recreated component or update the component according to key. The principle is:

  • Key is the same, the components change, react will only update the attributes corresponding to the changes of the components.
  • Key is different, the component will destroy the previous component and render the whole component again.

2. Problems Existing in Using index as key

2.1 Controlled Components

Simple display components such as span, these components are controlled components, which means that their values will be given by us.

If the subcomponent is only a controlled component and index is used as the key, there may not be any problem on the surface, but in fact the performance will be greatly affected. For example, the following code:

//['Zhang San',' Li Si',' Wang Wu'] = >
<ul>
< li key="0 "> Zhang San < /li >
< li key="1 "> Li si < /li >
< li key="2 "> Wang Wu < /li >
</ul>
//array rearrangement-> ['Wang Wu',' Zhang San',' Li si'] = >
<ul>
< li key="0 "> Wang Wu < /li >
< li key="1 "> Zhang San < /li >
< li key="2 "> Li si < /li >
</ul>

When the order of element data sources changes, the corresponding:

Components with key of 0, 1 and 2 have all changed, and all three sub-components will be re-rendered. (Re-rendering here is not destruction because key is still there.)

Instead, we use a unique id as the key:

//['Zhang San',' Li Si',' Wang Wu'] = >
<ul>
< li key="000 "> Zhang San < /li >
< li key="111 "> Li si < /li >
< li key="222 "> Wang Wu < /li >
</ul>
//array rearrangement-> ['Wang Wu',' Zhang San',' Li si'] = >
<ul>
< li key="222 "> Wang Wu < /li >
< li key="000 "> Zhang San < /li >
< li key="111 "> Li si < /li >
</ul>

According to the above update principle, the value and key of the subcomponents have not changed, only the order has changed, so react only moved them and did not render them again.

2.2 Uncontrolled Components

Components like input, which can be changed by users at will and are not controlled by us, may have problems when using index as the key. See chestnut below:

Subassembly:

render() {
 return (
 <div>
 < p > value: {this.props.value}</p >
 <input />
 </div>
 );
 }
 }

Parent component

{
this.state.data.map((element, index) => {
return <Child value={element} key={index} />
})
}

We enter the corresponding values in the first two input boxes respectively:

image

Then add an element to the header:

image

Obviously, this result does not meet our expectations. Let’s analyze what happened:

<div key="0">
 < p > value: 0</p >
 <input />
 </div>
 <div key="1">
 < p > value: 1</p >
 <input />
 </div>
 <div key="2">
 < p > value: 2</p >
 <input />
 </div>

After the change:

<div key="0">
 < p > value: 5</p >
 <input />
 </div>
 <div key="1">
 < p > value: 0</p >
 <input />
 </div>
 <div key="2">
 < p > value: 1</p >
 <input />
 </div>
 <div key="3">
 < p > value: 2</p >
 <input />
 </div>

It can be found that key 0, 1 and 2 have not changed. According to the rules, components will not be uninstalled, only the changed attributes will be updated.

React only diff the change of the value in the P tag, while the value in the input box has not changed, so it will not be re-rendered, only the value of the P tag will be updated.

When using a unique id as the key:

image

<div key="000">
< p > value: 0</p >
<input />
</div>
<div key="111">
< p > value: 1</p >
<input />
</div>
<div key="222">
< p > value: 2</p >
<input />
</div>

After the change:

<div key="555">
 < p > value: 5</p >
 <input />
 </div>
 <div key="000">
 < p > value: 0</p >
 <input />
 </div>
 <div key="111">
 < p > value: 1</p >
 <input />
 </div>
 <div key="222">
 < p > value: 2</p >
 <input />
 </div>

It can be clearly found that the components with key of 111,222,333 have not changed, react will not update them, but only newly inserted sub-component 555 and changed the positions of other components.

3. Choose key correctly

3.1 Pure Display

If the component is used for demonstration only and no other changes will occur, there is no problem in using index or any other different value as key, because diff will not occur and key will not be used.

3.2 Recommended Use of index

The use of index as key is not defective in any case, such as the following:

You need to render a list page by page. Each click on the page will render it again:

Use unique id:

First page
<ul>
< li key="000 "> Zhang San < /li >
< li key="111 "> Li si < /li >
< li key="222 "> Wang Wu < /li >
</ul>
Second pages
<ul>
< li key="333 "> Zhang sansan < /li >
< li key="444 "> Li si si < /li >
< li key="555 "> 55 < /li >
</ul>

After turning the page, the key and components of the three records have changed, so the three sub-components will be unloaded and re-rendered.

Use index:

First page
 <ul>
 < li key="0 "> Zhang San < /li >
 < li key="1 "> Li si < /li >
 < li key="2 "> Wang Wu < /li >
 </ul>
 Second pages
 <ul>
 < li key="0 "> Zhang sansan < /li >
 < li key="1 "> Li si si < /li >
 < li key="2 "> 55 < /li >
 </ul>

After turning the page, the key will not change, the sub-component value will change, and the component will not be unloaded, but only updated.

3.3 Subassemblies May Be Changed/Uncontrolled Components Used

In most cases, there will be no problem using a unique id as the key of the subcomponent.

This id must be unique and stable, which means that the id corresponding to this record must be unique and will never change.

It is not recommended to use math.random or other third-party libraries to generate unique values as keys.

Because when the data changes, the key of the same data may also change, thus rendering again, causing unnecessary performance waste.

If the data source does not meet our requirements, we can manually add a unique id to the data source before rendering, instead of adding it during rendering.