2017年年后嘶朱,團隊決定棄jQuery晕窑,將技術棧切到了React全家桶。筆者從業(yè)經驗少,在技術切換的過程中,邊學邊用,踩過很多坑,曾經因為小問題將自己繞的暈暈乎乎的开睡,也因此積累了一點經驗。因此決定將過去六個月中遇到的問題苟耻,學到的經驗以文章的形式記錄下來篇恒。在接下來團隊進一步擴大應用的過程中,仍然會繼續(xù)記錄凶杖。由于我本身就是新手胁艰,所以如果有看到的大神準備好了搬磚,請輕拍智蝠。
先從React基礎開始腾么,不涉及Redux。文章會用幾個小栗子來說明用到的知識點杈湾。項目會用Es6來寫React組件解虱,也會用到AntDesign。
(一)組件的key漆撞。
先從一個常見的警告開始吧殴泰。
“ Warning:Each child in an array or iterator should have a unique "key" prop. Check the render method of `App`. See https://fb.me/react-warning-keys for more information.”
上面這個警告想必每個剛開始寫React的童鞋遇到過于宙。警告的意思是,你沒有給React組件寫一個叫“key”的屬性值悍汛。這個報錯通常出現(xiàn)在對后端返回的數(shù)組進行map遍歷捞魁,然后生成一個個列表項。而React規(guī)范中离咐,每一個組件都要有一個唯一的key值谱俭。
解決這個問題也很好辦,就是指定key宵蛀。很多情況會直接使用map方法的第二個參數(shù)index作為組件的key昆著。其實這是一種不推薦的寫法。最好的key值是應該使用返回數(shù)據中的唯一標識來做組件的key(如果后端沒有給你返回類似Id术陶,key這種唯一標志性宣吱,當我沒說)。
為什么這么推薦瞳别?
首先要明白,為什么組件要有唯一標識key值杭攻。React是根據組件上設定的key屬性來生成該組件祟敛,只有key改變了,React才會更新組件兆解,否則重用該組件馆铁。
key相同,若組件屬性有所變化锅睛,則react只更新組件對應的屬性埠巨;沒有變化則不更新。 key值不同现拒,則react先銷毀該組件辣垒,然后重新創(chuàng)建。如果使用了index作為key值印蔬,這個index并沒有和返回的數(shù)據列表做一一對應勋桶,相當于是用了一個隨機值,本來這一項數(shù)據沒有改變侥猬,React組件可以被重用例驹,但是用了隨機值,組件會重新渲染退唠。
如果有兩個組件有相同的key值鹃锈,React則根據key認為兩個組件是完全相同的,后一個組件會被拋棄掉瞧预。
React的diff算法分為tree diff屎债,component diff和element diff仅政。在element diff中算法中,通過key進行算法優(yōu)化扔茅。
當節(jié)點處于同一層級時已旧,React diff 有三種節(jié)點操作,分別為:插入召娜、移動和 刪除运褪。
如果沒有key碘耳,假設老集合中包含節(jié)點:A陡蝇、B、C棋蚌,更新后的新集合中包含節(jié)點:B雅倒、C璃诀、A,此時新老集合進行對比蔑匣,發(fā)現(xiàn) B !== A劣欢,則創(chuàng)建B插入到集合,刪除老集合 A裁良;以此類推凿将,創(chuàng)建并插入C、A价脾,刪除 B牧抵、C。
節(jié)點很多的話侨把,這樣的操作會很消耗性能犀变。更加合理的方式是進行移動操作。
key存在秋柄,通過 key 發(fā)現(xiàn)新老集合中的節(jié)點都是相同的節(jié)點获枝,只需要將老集合中節(jié)點的位置進行移動,更新為新集合中節(jié)點的位置华匾。則可以把B和C移動到A的前面映琳。
唯一的key屬性不會顯性優(yōu)化性能,但是對React內部是有利的蜘拉。
下一篇聊聊React的數(shù)據原則:誰持有萨西,誰消費。