1. 程式人生 > >React-Component-Keys

React-Component-Keys

React渲染列表時,會遇到這樣的警告:

Warning: Each child in an array or iterator should have a unique "key" prop.   
Check the render method of `Game`. See https://fb.me/react-warning-keys for more information.

當你渲染一個列表時,React 通常會儲存列表中每一項的一些資訊。如果你渲染的元件擁有狀態,那麼這個狀態是需要被儲存的。並且,不管你的元件是如何實現的,React 都會儲存一個可以回退到原生檢視的引用。
當你更新列表時,React 需要明確發生了什麼變化——列表項增加、刪除、排序或者進行了更新。

想象一下列表由下面的狀態:

<li>Alexa: 7 tasks left</li>
<li>Ben: 5 tasks left</li>

變成了這樣:

<li>Ben: 9 tasks left</li>
<li>Claudia: 8 tasks left</li>
<li>Alexa: 5 tasks left</li>

以人類的思維來看,這個變化應該是 Alexa 和 Ben 交換了位置,並且 Claudia 是新增加的。但是,React 僅僅是計算機程式,它不知道你打算做什麼。因此,React 需要你為列表中的每一項指定一個key

屬性,這個屬性是一個字串,用來區分元件和它的兄弟姐妹們。在這個事例中,alexa, ben, claudia也許是合適的 keys。如果列表項資料與資料庫中儲存的格式一致,那麼資料 ID 通常是一個好的選擇:

<li key={user.id}>{user.name}: {user.taskCount} tasks left</li>

key 是 React 預留的一個特殊屬性(與 ref 一樣,ref 是一個高階特性)。當元素被建立的時候,React 會把 key 屬性直接儲存在返回的元素中。雖然它看起來像是 props 的一部分,但是它是不能通過 this.props.key

 來引用的。當元素更新時,React 會自動使用 key 來確定更新哪個元素,除此之外,元件沒有任何辦法去查詢它自己的 key。

當列表重新渲染的時候,React 會用新版本列表中的每一項和之前的列表進行 key 的比對。當一個 key 被新增時,一個元件就被建立了;當一個 key 被刪除時,一個元件被銷燬了。Keys 告訴了 React 每個元件的身份標識,所以,重新渲染的時候,它能夠維持元件的狀態。如果你改變了一個元件的key,那麼它將會被完全銷燬並且重新建立一個擁有新狀態的元件。

強烈推薦,無論何時,你建立動態列表的時候,都要指定合適的 keys。如果你實在是沒有合適的 key,你也許應該考慮重新調整你的資料,以便你能夠找到一個合適的 key。

如果你不指定任何 key,React 將會警告你並且回退去使用陣列的索引來作為 key。這當然不是一個正確的選擇了,因為你通常會為你的列表重新排序等等,除非新增或者刪除操作都只發生在列表的底部。顯式地通過 key={i} 可以消除警告,但是在很多情況下這樣做是有問題的,所以不推薦。

元件的 keys 不需要全域性唯一,僅僅讓直接兄弟姐妹唯一就可以了。