react反模式之index做爲key

react反模式之index做爲key

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

我已經看到過不少React開發人員在渲染一個列表時使用index做爲它的keyreact

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

這樣寫看起來很優雅而且確實擺脫了react的警告信息,那麼這樣寫有危險的地方嗎?


  這樣會破壞你的應用讓其顯示出錯誤的數據 git

下面我來解釋下,key是React來識別DOM元素的惟一屬性。若是你往數組裏面增長一些元素或者從數組中間移除一些東西會發生些什麼呢?若是key屬性和之前同樣React會認爲DOM元素表示的組件和之前是同樣的,可是那是錯誤的。github

這裏我有個簡單的例子來演示這個潛在的危險源碼
index錯誤例子npm

事實證實,React 會用index做爲默認的key的值由於這個時候React認爲用index是最合理的。所以,React會警告你那樣作是爲達標準的(這樣說看起來有點困惑. 若是你本身提供了key屬性React會認爲你知道本身在作啥. 記住這個例子,它可能會致使錯誤。數組

Better

列表裏面的每一項都應該又一個永久而且惟一的屬性,理想狀況下應該在建立列表的時候分配下去. 固然我指的是id. 咱們能夠像下面這樣使用它:ui

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

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

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

Much better

一個產品化的解決方案是它應該更加健壯,可以用來建立分散的列表項. 所以我強烈推薦一個npm包shortid, 它能夠快速的生成一系列‘短的 無序的 對url友好的 惟一的’ id,下面是示例代碼:spa

var shortid = require('shortid');

function createNewTodo(text) {
    return {
        completed: false,
        id: shortid.generate(),
        text
    }
}

TL;DR: 爲每一個列表項生成一個惟一的id,而後在渲染列表項時做爲key屬性傳給列表項.code

References and related articles

. Dynamic Childrenand Keyed Fragments in React Docs
. Explanation from Paul O’Shannessy
. The importance of component keys in React.js
. React.js and Dynamic Children — Why the Keys are Important

相關文章
相關標籤/搜索