在react中,如果要渲染一個列表,我們會用map()函數(shù)將數(shù)組循環(huán)處理然后渲染到DOM,在處理循環(huán)時,“key” 是一個你需要包含的特殊字符串屬性。
很多時候,我們會使用當(dāng)前列表的索引為key,但這樣做真的好嗎?
要討論這個問題,我們要從react的原理說起,我們react的執(zhí)行步驟一般是:用state和jsx模板生成虛擬DOM,然后用虛擬DOM生成真實的 DOM,當(dāng)我們state發(fā)生變化時,render函數(shù)執(zhí)行,生成新的 虛擬DOM,然后比較新舊虛擬DOM的區(qū)別,找到區(qū)別,然后直接操作DOM,改變有區(qū)別的內(nèi)容,這樣比傳統(tǒng)的操作DOM,極大的提升了性能。
再說虛擬DOM,虛擬DOM其實就是一個JS對象(['div',{class:'app'},'item']),虛擬DOM核心之一是diff算法,diff算法的核心之一是同層對比,如圖:
如果在第一層div時就有出現(xiàn)區(qū)別,那么對比結(jié)束,直接更新真實DOM中對應(yīng)的當(dāng)前節(jié)點,以此類推。。。
再說說key,假設(shè)我們在state中有一個列表[a,b,c],在遍歷渲染時用索引作為key,那么就是這樣:
a 0
b 1
c 2
如果我們執(zhí)行一個操作,點擊刪除數(shù)組中的a, 我們的列表就是[b,c],在遍歷渲染時仍然會用索引作為key,結(jié)果如下:
b 0
c 1
如圖 ,我們?nèi)绻挥盟饕秊閗ey , 程序能快速的對比出差異,反之也能對出差異,但是必須對比整個虛擬DOM,
這樣,程序仍然能正常執(zhí)行,只不過大大消耗了新舊虛擬DOM的對比的性能,并可能導(dǎo)致組件狀態(tài)問題。