React Lists and Keys
產生一個 React 元素清單 (lists; collections) 就跟操作 JavaScript Array 差不多。
例如:
// 一個正常的 JavaScript Array
const numbers = [1, 2, 3, 4, 5];
// 你可以產生一個 React 元素陣列
// 陣列中每個元素都是一個 React element (JSX)
const listItems = numbers.map((numbers) =>
<li>{numbers}</li>
);
// 將所有的 <li> 元素都放到 <ul> 元素下面
ReactDOM.render(
<ul>{listItems}</ul>,
document.getElementById('root')
);
最後顯示到畫面的 HTML:
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
</ul>
你也可以在 JSX 的 { }
中用 inline 的寫法:
const numbers = [1, 2, 3, 4, 5];
ReactDOM.render(
<ul>
{numbers.map((numbers) =>
<li key={numbers.toString()}>{numbers}</li>
)}
</ul>,
document.getElementById('root')
);
執行上面的例子,你可能有發現在 console 中 React 給你一個警告訊息是:
Warning: Each child in an array or iterator should have a unique 'key' prop.
字面上的意思是,你需要給陣列中的每一個 React 元素一個唯一的編號 (unique key),編號是字串型態,設定在 key
這個屬性上。那為什麼會有這個要求呢?因為 React 需要知道實際上哪個元素是哪一個,React 的 Virtual DOM Diff 演算法才能確定哪些元素是需要在 DOM 中被新增的、哪些是要更新的、哪些是要被刪除的。
React 用
key
在陣列中判斷是不是同一個元素物件。所以上面的例子應該修正為:
const numbers = [1, 2, 3, 4, 5];
// 為每個 React 元素加上獨一無二的 key 編號
const listItems = numbers.map((numbers) =>
<li key={numbers.toString()}>{numbers}</li>
);
ReactDOM.render(
<ul>{listItems}</ul>,
document.getElementById('root')
);
如果每個元素不好想出個編號,或陣列中的元素順序是固定不變的,你也可以利用 map function 的第二個 index 參數像這樣子產生編號:
const todoItems = todos.map((todo, index) =>
// 利用 map function 的第二個 index 參數
<li key={index}>
{todo.text}
</li>
);
key 編號只需要在同一個陣列清單中是不重複 (unique) 的即可。
key
只會被 React 拿來自己用,不會被傳進元件 props 中喔,如果你需要用到這個 key 值,你需要另外自己傳進去,像是:
const content = posts.map((post) =>
<Post
key={post.id}
id={post.id}
title={post.title} />
);