摘要:前言是唯一一個(gè)用來(lái)分辨子元素的標(biāo)識(shí)。在元素?cái)?shù)組中,應(yīng)該被賦予給每個(gè)元素,從而每個(gè)元素都有一個(gè)穩(wěn)定的身份證明。注意事項(xiàng)值并不是需要全局唯一,而只需要在相鄰的兄弟元素中唯一就好。不要使用的來(lái)做為值,因?yàn)槿绻捻樞虬l(fā)生改變,那么值也會(huì)發(fā)生改變。
前言
key是React唯一一個(gè)用來(lái)分辨子元素的標(biāo)識(shí)。如果我們動(dòng)態(tài)創(chuàng)建子React元素,而且這些子元素的順序或者數(shù)量不確定的時(shí)候,那么就需要使用key這個(gè)屬性。
不使用key,可能出現(xiàn)的錯(cuò)誤Key的使用允許React來(lái)分辨哪些元素改變了,哪些是增加的,那些被刪除了。在元素?cái)?shù)組中,key應(yīng)該被賦予給每個(gè)元素,從而每個(gè)元素都有一個(gè)穩(wěn)定的身份證明。
可能會(huì)造成渲染錯(cuò)誤
我之前做了一個(gè)2048的小游戲,但是在移動(dòng)的時(shí)候,總是會(huì)出現(xiàn)跳的現(xiàn)象:
可能會(huì)出現(xiàn)數(shù)據(jù)的錯(cuò)誤
舉個(gè)例子,目的是可以在最上方增加輸入行:
export default class List extends React.Component { index = 3 constructor(props) { super(props); this.state = { list: [2,1] }; } insert = ()=>{ let list = [this.index++, ...this.state.list]; this.setState({ list }); } render(){ return (); } } export default class Item extends React.Component { constructor(props) { super(props); this.state = { input: "" }; } onChange = (e)=>{ this.setState({ input: e.target.value }) } render(){ return ({ this.state.list.map(value=>{ return
- }); }
看著似乎沒(méi)有問(wèn)題,但是由于缺少key值,會(huì)造成一個(gè)bug:
由上面的GIF中可以看到,原來(lái)在Input 2里面輸入的值變成Input 3的值了,這是為什么?
由于沒(méi)有使用key,造成React靠順序來(lái)判斷子元素,所以就造成了Input 2的元素,修改props成Input 3,而原本里面存著的state并沒(méi)有發(fā)生變化,所以就顯示的是Input 3的輸入域里面顯示著原本Input 2的值。
同理,Input 1變成了Input 2,然后又重新生成了一個(gè)Input 1.
而如果我們使用了key,
render(){ return (); }{ this.state.list.map(value=>{ return
- }); }
那么React就會(huì)很容易的辨別子元素,會(huì)變成下面這個(gè)樣子,就不會(huì)造成上面的錯(cuò)誤了:
就像之前的那個(gè)例子里所展示,不加Key可能會(huì)造成更多的渲染。
我們?cè)?b>Item里面加一個(gè)shouldComponentUpdate的判斷:
shouldComponentUpdate(nextProps, nextState){ return nextProps.value != this.props.value || this.state.input !== nextState.input; }
這樣子保證當(dāng)value和state不改變的時(shí)候,不會(huì)調(diào)用re-render。
我們可以通過(guò)React Performance Tool的Perf來(lái)看一下渲染次數(shù)的對(duì)比。
首先,我們?cè)黾訋讉€(gè)功能reverse(調(diào)轉(zhuǎn)), insert(插入到第一個(gè)) 和 delete(刪除第一個(gè))
其次,我們規(guī)定的步驟是1. insert 2.insert 3.reverse 4.delete,來(lái)看一看渲染的次數(shù)
下面是打印的結(jié)果:
沒(méi)有使用Key
使用Key
對(duì)比效果很明顯,沒(méi)有使用key的時(shí)候,render了14次。而使用key的時(shí)候,只render了2次(2次insert)。中間的差別很大,時(shí)間也差很多。
key的其他用法看了這篇文章發(fā)現(xiàn)了一個(gè)很有趣的用法.
按照作者所說(shuō),如果同一個(gè)組件,如果要修改其中的一些props會(huì)造成很多數(shù)據(jù)重新計(jì)算,可能會(huì)寫(xiě)很多判斷邏輯,有的時(shí)候還是不如直接重新全部刪除重新計(jì)算。
有的時(shí)候你想要銷毀和重建組件,觸發(fā)componentDidMount方法,重置state。那么就可以使用key這個(gè)屬性。當(dāng)你要銷毀、重建組件的時(shí)候,你就可以通過(guò)改變key值來(lái)達(dá)到這個(gè)目的。
詳細(xì)的可以看看上面的文章鏈接。
注意事項(xiàng)key值并不是需要全局唯一,而只需要在相鄰的兄弟元素中唯一就好。
不要使用array的index來(lái)做為key值,因?yàn)槿绻?b>array的順序發(fā)生改變,那么key值也會(huì)發(fā)生改變。就會(huì)造成上面舉的例子的那種問(wèn)題。
排版有點(diǎn)亂。。。我會(huì)繼續(xù)修改
以上
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/81469.html
摘要:接上文完整流程圖見(jiàn)繼續(xù)我們的之旅,讓我們從的調(diào)用開(kāi)始。他們就是用來(lái)表示組件方法的返回值,除此之外,沒(méi)有其他的。同時(shí),在的創(chuàng)建期間,將會(huì)合并和如果有聲明的話,并且嚴(yán)重。顯然,這一步驟會(huì)引起一些性能問(wèn)題。 接上文--- 完整流程圖見(jiàn):https://bogdan-lyashenko.gith...繼續(xù)我們的React之旅,讓我們從ReactDOM.render的調(diào)用開(kāi)始。 ReactDOM...
摘要:前言在應(yīng)用開(kāi)發(fā)中,列表是我們使用頻率非常高的一種展現(xiàn)形式,在項(xiàng)目中更是如此。無(wú)處不在的使用更是需要我們小心觸發(fā)性能瓶頸的深水炸彈。不要用索引當(dāng)值要求我們對(duì)列表中的每一項(xiàng)設(shè)置一個(gè)唯一的值,這個(gè)虛擬的算法有很大關(guān)系。 前言 在應(yīng)用開(kāi)發(fā)中,列表是我們使用頻率非常高的一種展現(xiàn)形式,在reactjs項(xiàng)目中更是如此。無(wú)處不在的使用更是需要我們小心觸發(fā)性能瓶頸的深水炸彈。 下面就我最近的總結(jié)出的幾點(diǎn)...
摘要:所以為了簡(jiǎn)化流程,這些的代碼都先暫時(shí)忽略了。也就是說(shuō),每個(gè)平臺(tái)都有獨(dú)立的實(shí)現(xiàn)。我們將調(diào)試兩個(gè)過(guò)程,和分別對(duì)應(yīng)掛載和更新兩個(gè)階段。 概述:先看看React的架構(gòu)圖:https://bogdan-lyashenko.gith... 好好看一下上圖,初看看起來(lái)好像很復(fù)雜,但是事實(shí)上,它只描述了兩個(gè)過(guò)程:掛載和更新。由于卸載在某種程度上就是反掛載,上圖中我們移除了卸載的過(guò)程,以使得流程圖看起來(lái)...
摘要:接著,將返回的元素和之前的進(jìn)行比較的,以驗(yàn)證是否真的需要更新。我們看下代碼,代碼比較簡(jiǎn)單好,對(duì)應(yīng)于我們的這個(gè)列子,我們對(duì)于方法的更改并不會(huì)對(duì)方法造成影響。所以我們進(jìn)入下一步,也就是對(duì)于節(jié)點(diǎn)的更新。 接上文, React流程圖:https://bogdan-lyashenko.gith... 如果組件真的需要更新 在組件剛開(kāi)始更新過(guò)程時(shí),如果有定義componentWillUpdate方...
摘要:宋體以像素為單位控制字號(hào)。將其設(shè)置為可隱藏窗格。是否已啟用自動(dòng)刷新是否啟用自動(dòng)拉取以像素為單位控制終端的字號(hào),這是的默認(rèn)值。要求工作區(qū)使用高于版本的。 用戶設(shè)置 打開(kāi) 文件 > 首選項(xiàng) > 用戶設(shè)置(U),(忽略覆蓋工作區(qū)提示) { // 一個(gè)制表符等于的空格數(shù)。該設(shè)置在 `editor.detectIndentation` 啟用時(shí)根據(jù)文件內(nèi)容進(jìn)行重寫(xiě)。 editor.tabS...
閱讀 2028·2021-11-08 13:14
閱讀 2935·2021-10-18 13:34
閱讀 2023·2021-09-23 11:21
閱讀 3583·2019-08-30 15:54
閱讀 1752·2019-08-30 15:54
閱讀 2921·2019-08-29 15:33
閱讀 2570·2019-08-29 14:01
閱讀 1941·2019-08-29 13:52