-
Notifications
You must be signed in to change notification settings - Fork 3
/
Understanding react key.md
141 lines (109 loc) · 3.48 KB
/
Understanding react key.md
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
# Understanding React key
> Keys give the react elements a stable `identity`
## warning in array without key
```jsx
import React from 'react';
function App() {
const persons = [‘mike’, ‘jason’, ‘sharky’];
return <ul>
{persons.map(p => {
return <li>{p}</li>
})}
</ul>
}
```
React will throw a warning with the code above:
`Warning: Each child in a list should have a unique "key" prop.`
## What keys to use?
Keys should be `unique` and `stable`
### Index ? Maybe, but only `under some circumstances`
Array index is unique across an array.
```jsx
import React, { useState } from 'react';
function App() {
const persons = [‘mike’, ‘jason’, ‘sharky’];
return <ul>
{persons.map((p, index) => {
return <li key={index}>{p}</li>
})}
</ul>
}
```
However, if the order/number of items may change, array index is NOT `stable`.
```jsx
import React, { useState } from 'react';
function App() {
const [persons, setPersons] = useState(
['mike', 'jason', 'sharky']
);
const onAdd = () => {
setPersons(['fishman', ...persons])
}
return <>
<button onClick={onAdd}> Add fishman on top </button>
<ul>
{persons.map((p, index) => {
return <li key={index}><input type="checkbox"/>{p}</li>
})}
</ul>
</>
}
```
[array-index-as-key demo](https://codesandbox.io/s/staging-resonance-vy7eq)
Ticking `mike` and then clicking the add button will result in the loss of check status of `mike`
### `Stable` key
Usually we will have a unique and stable `id` like property for each record from backend/database.
```jsx
import React, { useState } from ‘react’;
export default function App() {
const [persons, setPersons] = useState(
[
{id: 'uywoejk', name: 'mike'},
{id: 'woeioqj', name: 'jason'},
{id: 'eljlkqd', name: 'sharky'}
]
);
const onAdd = () => {
setPersons([{
id: 'wuioeioe', name: 'fishman'
}, ...persons])
}
return <>
<button onClick={onAdd}> Add fishman on top </button>
<ul>
{
persons.map((p, index) => {
return <li key={p.id}><input type="checkbox"/>{p.name}</li>
})
}
</ul>
</>
}
```
[stable-key demo](https://codesandbox.io/s/gallant-visvesvaraya-0b3lo)
## Use key to unmount component
Use case: I have a select and input component. Each the select option changes, reset the input to default state,
```jsx
import React, { useState } from “react”;
export default function App() {
const [option, setOption] = useState("");
return (
<>
<select onChange={e => setOption(e.target.value)}>
<option key="a">A</option>
<option key="b">B</option>
</select>
<input defaultValue="this is default"/>
<input key={option} defaultValue="this is default" />
</>
);
}
```
[react-key demo](https://codesandbox.io/s/react-key-yth0y?file=/src/App.js:0-97)
## Conclusion
* `key` is an unique identifier for react element
* `key` should be `unique` and `stable`. A react element with different `key` in different render phases will be considered as different elements. The old one will be unmounted and a new one is created.
* Only use array indices as keys when the number/order of array items are unchanged across the whole app lifecycle.
* Always prefer to use backend/database unique identifier id like property as `key`
## Notice
* If you want to follow the latest news/articles for the series of my blogs, Please [「Watch」](https://github.com/n0ruSh/blogs/)to Subscribe.