原文: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。