|
導(dǎo)讀網(wǎng)頁的本質(zhì)就是超級文本標(biāo)記語言,通過結(jié)合使用其他的Web技術(shù)(如:腳本語言、公共網(wǎng)關(guān)接口、組件等),可以創(chuàng)造出功能強(qiáng)大的網(wǎng)頁。因而,超級文本標(biāo)記語言是萬維網(wǎng)(Web)編程的基礎(chǔ),也就是說萬維網(wǎng)是建立... 網(wǎng)頁的本質(zhì)就是超級文本標(biāo)記語言,通過結(jié)合使用其他的Web技術(shù)(如:腳本語言、公共網(wǎng)關(guān)接口、組件等),可以創(chuàng)造出功能強(qiáng)大的網(wǎng)頁。因而,超級文本標(biāo)記語言是萬維網(wǎng)(Web)編程的基礎(chǔ),也就是說萬維網(wǎng)是建立在超文本基礎(chǔ)之上的。超級文本標(biāo)記語言之所以稱為超文本標(biāo)記語言,是因?yàn)槲谋局邪怂^“超級鏈接”點(diǎn)。 本篇文章給大家?guī)淼膬?nèi)容是關(guān)于react中key的具體使用方法介紹(代碼示例),有一定的參考價值,有需要的朋友可以參考一下,希望對你有所幫助。
在開發(fā)react程序時我們經(jīng)常會遇到這樣的警告,然后就會想到:哦!循環(huán)子組件忘記加key了~ 出于方便,有時候會不假思索的使用循環(huán)的索引作為key,但是這樣真的好嗎?什么樣的值才是key的最佳選擇? 為了弄明白,本文將從三個方面來分析"key": 1.為什么要使用key 2.使用index做key存在的問題 3.正確的選擇key 1.為什么要使用key react官方文檔是這樣描述key的: Keys可以在DOM中的某些元素被增加或刪除的時候幫助React識別哪些元素發(fā)生了變化。因此你應(yīng)當(dāng)給數(shù)組中的每一個元素賦予一個確定的標(biāo)識。 react的diff算法是把key當(dāng)成唯一id然后比對組件的value來確定是否需要更新的,所以如果沒有key,react將不會知道該如何更新組件。 你不傳key也能用是因?yàn)閞eact檢測到子組件沒有key后,會默認(rèn)將數(shù)組的索引作為key。 react根據(jù)key來決定是銷毀重新創(chuàng)建組件還是更新組件,原則是:
2.使用index做key存在的問題 2.1 受控組件 單純的展示組件比如span,這些組件是受控組件,意味著他們的值將是我們給定好的。 如果子組件只是受控組件,使用index作為key,可能表面上不會有什么問題,實(shí)際上性能會受很大的影響。例如下面的代碼: // ['張三','李四','王五']=>
<ul>
<li key="0">張三</li>
<li key="1">李四</li>
<li key="2">王五</li>
</ul>
// 數(shù)組重排 -> ['王五','張三','李四'] =>
<ul>
<li key="0">王五</li>
<li key="1">張三</li>
<li key="2">李四</li>
</ul>當(dāng)元素?cái)?shù)據(jù)源的順序發(fā)生改變時,對應(yīng)的: key為0,1,2的組件都發(fā)生了變化,三個子組件都會被重新渲染。(這里的重新渲染不是銷毀,因?yàn)閗ey還在) 相反,我們使用唯一id作為key: // ['張三','李四','王五']=>
<ul>
<li key="000">張三</li>
<li key="111">李四</li>
<li key="222">王五</li>
</ul>
// 數(shù)組重排 -> ['王五','張三','李四'] =>
<ul>
<li key="222">王五</li>
<li key="000">張三</li>
<li key="111">李四</li>
</ul>根據(jù)上面的更新原則,子組件的值和key均未發(fā)生變化,只是順序發(fā)生改變,因此react只是將他們做了移動,并未重新渲染。 2.2 非受控組件 像input這樣可以由用戶任意改變值,不受我們控制的組件,在使用了index作為key時可能會發(fā)生問題,看如下的栗子: 子組件: render() {
return (
<p>
<p >值:{this.props.value}</p>
<input />
</p>
);
}
}父組件 {
this.state.data.map((element, index) => {
return <Child value={element} key={index} />
})
}我們在前兩個輸入框分別輸入對應(yīng)的值:
然后在頭部添加一個元素:
很明顯,這個結(jié)果并不符合我們的預(yù)期,我們來分析一下發(fā)生了什么: <div key="0">
<p >值:0</p>
<input />
</div>
<div key="1">
<p >值:1</p>
<input />
</div>
<div key="2">
<p >值:2</p>
<input />
</div>變化后: <div key="0">
<p >值:5</p>
<input />
</div>
<div key="1">
<p >值:0</p>
<input />
</div>
<div key="2">
<p >值:1</p>
<input />
</div>
<div key="3">
<p >值:2</p>
<input />
</div>可以發(fā)現(xiàn):key 0,1,2并沒有發(fā)生改變,根據(jù)規(guī)則,不會卸載組件,只會更新改變的屬性。 react只diff到了p標(biāo)簽內(nèi)值的變化,而input框中的值并未發(fā)生改變,因此不會重新渲染,只更新的p標(biāo)簽的值。 當(dāng)使用唯一id作為key后:
<div key="000">
<p >值:0</p>
<input />
</div>
<div key="111">
<p >值:1</p>
<input />
</div>
<div key="222">
<p >值:2</p>
<input />
</div>變化后: <div key="555">
<p >值:5</p>
<input />
</div>
<div key="000">
<p >值:0</p>
<input />
</div>
<div key="111">
<p >值:1</p>
<input />
</div>
<div key="222">
<p >值:2</p>
<input />
</div>可以很明顯的發(fā)現(xiàn):key為 111,222,333的組件沒有發(fā)生任何改變,react不會更新他們,只是新插入了子組件555,并改變了其他組件的位置。 3.正確的選擇key 3.1 純展示 如果組件單純的用于展示,不會發(fā)生其他變更,那么使用index或者其他任何不相同的值作為key是沒有任何問題的,因?yàn)椴粫l(fā)生diff,就不會用到key。 3.2 推薦使用index的情況 并不是任何情況使用index作為key會有缺陷,比如如下情況: 你要分頁渲染一個列表,每次點(diǎn)擊翻頁會重新渲染: 使用唯一id: 第一頁
<ul>
<li key="000">張三</li>
<li key="111">李四</li>
<li key="222">王五</li>
</ul>
第二頁
<ul>
<li key="333">張三三</li>
<li key="444">李四四</li>
<li key="555">王五五</li>
</ul>翻頁后,三條記錄的key和組件都發(fā)生了改變,因此三個子組件都會被卸載然后重新渲染。 使用index: 第一頁
<ul>
<li key="0">張三</li>
<li key="1">李四</li>
<li key="2">王五</li>
</ul>
第二頁
<ul>
<li key="0">張三三</li>
<li key="1">李四四</li>
<li key="2">王五五</li>
</ul>翻頁后,key不變,子組件值發(fā)生改變,組件并不會被卸載,只發(fā)生更新。 3.3 子組件可能發(fā)生變更/使用了非受控組件 大多數(shù)情況下,使用唯一id作為子組件的key是不會有任何問題的。 這個id一定要是唯一,并且穩(wěn)定的,意思是這條記錄對應(yīng)的id一定是獨(dú)一無二的,并且永遠(yuǎn)不會發(fā)生改變。 不推薦使用math.random或者其他的第三方庫來生成唯一值作為key。 因?yàn)楫?dāng)數(shù)據(jù)變更后,相同的數(shù)據(jù)的key也有可能會發(fā)生變化,從而重新渲染,引起不必要的性能浪費(fèi)。 如果數(shù)據(jù)源不滿足我們這樣的需求,我們可以在渲染之前為數(shù)據(jù)源手動添加唯一id,而不是在渲染時添加。 以上就是react中key的具體使用方法介紹(代碼示例)的詳細(xì)內(nèi)容,更多請關(guān)注php中文網(wǎng)其它相關(guān)文章! 網(wǎng)站建設(shè)是一個廣義的術(shù)語,涵蓋了許多不同的技能和學(xué)科中所使用的生產(chǎn)和維護(hù)的網(wǎng)站。 |
溫馨提示:喜歡本站的話,請收藏一下本站!