key
props
- 每一個 React component 在實例化時,都可以綁定一個 key 給它
1 | ... |
- key 即 Virtual DOM 的
身分證
- 當 VDOM Tree 中某個 node 上一次與這一次的 key 值不同, 即視為
不同 node
- 因此可利用變化 key 的技巧, 來強迫 Component
remount
- 當 VDOM Tree 中某個 node 上一次與這一次的 key 值不同, 即視為
Use Array's index
as key v.s. Use uniqle uuid
as key
假設有一個 Array
1 | const array = ['apple', 'banana', 'grape']; |
將這個 array 的 value 透過 Item Component 呈現 (使用 ‘label’ 這個 props 灌下去)
1 | class App extends React.PureComponents { |
1 | class Item extends React.PureComponent { |
以插入元素(‘peach’)到 Array 的頭為例,陣列變成
1 | ['peach', 'apple', 'banana', 'grape'] |
index as key
1
2
3
4
5
6
7
8
9
10
11
12// 螢幕上呈現
peach --- apple
apple --- banana
banana --- grape
grape --- grape
// console .
peach render!
apple render!
banana render!
grape mount!
grape render!前後的 key 比較
1
2
3Old: 0 - 1 - 2
| | |
New: 0 - 1 - 2 - 3舊的 React DOM 有 key 0, 1, 2 這三個 node, 而新的 React DOM 新增了一個 key 為 3 的 node .
- React 判斷 0, 1, 2 這三個 node
更動了 'label' props
(e.g. 0 這個 node 的 label 從 ‘apple’ 變成 ‘peach’),因此只 re-render
, 也就是他們其實都維持原本的 instance
, 沒有經過 unmount => 一開始在componentWillMount() 設定的 this.label 維持不變
. - key 為 3 為新的 node, 建立新的 instance => mount
label as key (uniqle key)
1
2
3
4
5
6
7
8
9// 螢幕上呈現
peach --- peach
apple --- apple
banana --- banana
grape --- grape
// console .
peach mount!
peach render!前後的 key 比較
1
2
3Old: apple - banana - grape
\ \ \
New: peach - apple - banana - grape以 apple, banana, grape 為 key 的 instance, 因為
沒有任何新的 props 傳下去
, 不會 re-render 也不會 unmount- 以 peach 為 key 的 instance 是新的 => mount
Sample code: React key
Use index as key 可能
會遇到的問題
Performance issue
- 不必要的 re-render
結果呈現不如預期
- React 判斷前後為同一個 instance, 但實際上並非如此