index做爲key是反模式

原文:Index as a key is an anti-patternhtml

我曾屢次看到開發者在渲染列表的時候把列表項的index做爲它的key。react

{todos.map((todo, index) =>
  <Todo {...todo}
    key={index} />
)}

這看起來很優雅,並且可以解決警告(這纔是「真」問題,對吧?)的問題,這樣作有什麼危險呢?git

It may break your application and display wrong data!github

讓我來解釋,key是React惟一用來肯定DOM元素的東西,若是你想列表增長一項或移除中間的某項,會發生什麼事?若是key和以前一個同樣React就會假定這個DOM元素和以前對應的組件是一個,可是它們可能並非同一個了。npm

爲了證實潛在的危險我建立了一個簡單示例app

圖片描述

這代表,若是不指定key的時候React會使用index,由於這是那個時候最好的猜想,並且它會警告你說這不是最優解(它經過使人困惑的語句表述這個意思)。若是你主動提供了它,React就認爲你知道你在幹什麼。記住這個示例,它能產生不可預測的結果。ui

比較好

像這樣的應該都有一個永久的惟一的屬性,當列表項建立的時候它是最合適被設置爲key的,顯然我是在說id,咱們能夠用下面的方式使用它:url

{todos.map((todo) =>
  <Todo {...todo}
    key={todo.id} />
)}

另外的實現方式是把編號遞增移動到抽象方法中,使用一個全局的index來確保任何兩個列表項的id不一樣。spa

todoCounter = 1;
function createNewTodo(text) {
  return {
    completed: false,
    id: todoCounter++,
    text
  }
}

更好

一個產品級別的方案應該是一個更健壯的方法,可以處理分散建立列表項。所以,我推薦使用shortid。它可以快速生成「短 無序 url友好 惟一」的id,代碼像下面這樣:code

var shortid = require('shortid');
function createNewTodo(text) {
  return {
    completed: false,
    id: shortid.generate(),
    text
  }
}

TL;DR:爲每一個列表項生成一個惟一的id,並在渲染列表的時候使用它做爲key。

參考和相關文章

相關文章
相關標籤/搜索