iT邦幫忙

2021 iThome 鐵人賽

DAY 24
0
自我挑戰組

登堂入室!前端工程師的觀念技術 _30_ 題系列 第 24

23. React key 的用途

用途


  • key 是一個建立陣列(array)時,必須使用的字串 屬性(string attribute)
  • React 會用 key 來分辨陣列裡元素(element),辨別元素的改變或增減。

component instance 是基於它們的 key 來決定是否更新以及重複使用。

示例


這裡示範一個數字的list:

const App = () => {
	const numbers = [1, 2, 3, 4, 5];
	const listItems = numbers.map((number) =><li>{number}</li>);
	return(
	  <div>
			<ul>{listItems}</ul>
  	</div>
	)
};

ReactDOM.render(<App/>, document.getElementById("root"));

雖然成功渲染畫面了,但會跳出像這樣的錯誤訊息:

"Warning: Each child in a list should have a unique 'key' prop.

這是因為React需要藉由key來辨別項目,所以必須指定key給陣列裡的元素:

const id = [11, 22, 33, 44, 55];  // 指定一個id陣列

const App = () => {
	const numbers = [1, 2, 3, 4, 5];
	const listItems = numbers.map((number) =>
		<li key={id.toString()}>
				{number}
		</li>
	);
	return(
	  <div>
			<ul>{listItems}</ul>
  	</div>
	)
};

ReactDOM.render(<App/>, document.getElementById("root"));

不建議使用索引作為key值

如果陣列的項目沒有被分配 key,React 預設將會使用索引作為 key。
但在項目順序可能改變的情況下,官方並不建議使用索引作為 key。

原因是,

  1. 會影響效能。(diff變慢,這跟React預測元件更新的diffing演算法有關,可以參閱官方文件)
  2. 因為key是基於索引值,因此如果更動順序,也會修改當前的key,可能會導致不合預期的結果。

錯誤的情況可以參考重新了解React中的key (Part 1),文章裡面的舉例很清楚!

當使用 array 索引值作為 key 的 component 進行重新排序時,component state 可能會遇到一些問題。由於 component instance 是基於它們的 key 來決定是否更新以及重複使用,如果 key 是一個索引值,那麼修改順序時會修改目前的 key,導致 component 的 state(例如不受控制輸入框)可能相互篡改導致無法預期的變動。


兩個不同的 array ,可以使用相同的 key

在同一個陣列裡,每個被指定的 key 都必須是唯一值,這樣React才可以辨別他們的身分。

但不同的陣列,也可以套用相同的key值。

const id = [11, 22, 33, 44, 55];

const App = () => {
	const numbers = [1, 2, 3, 4, 5];
	const people = ["Winnie", "Mary", "Tina"];
	
	const listItems = numbers.map((number) => 
		<li key={id.toString()}>    // 指定id為key
				{number}
		</li>
	);
																
	const nameList = people.map((name) =>
		<li key={id.toString()}>    // 指定id為key
				{name}
		</li>
	);
	
	return(
	  <div>
			<ul>{listItems}</ul>
			<ul>{nameList}</ul>
  	</div>
	)
};

ReactDOM.render(<App/>, document.getElementById("root"));

由此可知,因為key是給陣列裡的元素辨別用,因此兩個陣列可以指定相同的key值。


component 不能讀取 props 裡的 key

Key 的功能是提示 React,但它們不會被傳遞到元件裡。

所以如果希望key值被傳進元件,可以嘗試這樣的做法:

const content = example.map((post) =>
  <Example
    key={post.id}
    id={post.id}
  />
);

雖然component不能讀取 props.key,但因為props.id還是會被傳進元件,就可以沿用props的特性重複使用key值。

【如內文有誤還請不吝指教>< 並感謝閱覽至此的各位:D 】

參考資料 :
-列表與 Key – React
-Reconciliation
-React Lists | Keys - React 教學 Tutorial

---正文結束---


上一篇
22. React Hooks --- useEffect
下一篇
24. 解釋 immutable / immutability
系列文
登堂入室!前端工程師的觀念技術 _30_ 題31

尚未有邦友留言

立即登入留言