在react項(xiàng)目中總會(huì)遇到這樣一個(gè)的坑
創(chuàng)新互聯(lián)建站是專(zhuān)業(yè)的鋼城網(wǎng)站建設(shè)公司,鋼城接單;提供成都網(wǎng)站制作、網(wǎng)站建設(shè),網(wǎng)頁(yè)設(shè)計(jì),網(wǎng)站設(shè)計(jì),建網(wǎng)站,PHP網(wǎng)站建設(shè)等專(zhuān)業(yè)做網(wǎng)站服務(wù);采用PHP框架,可快速的進(jìn)行鋼城網(wǎng)站開(kāi)發(fā)網(wǎng)頁(yè)制作和功能擴(kuò)展;專(zhuān)業(yè)做搜索引擎喜愛(ài)的網(wǎng)站,專(zhuān)業(yè)的做網(wǎng)站團(tuán)隊(duì),希望更多企業(yè)前來(lái)合作!
這是警告數(shù)組遍歷子元素要有一個(gè)唯一的key值,但是key到底是什么,在代碼中到底起了什么作用?
key概述
react中的key屬性,它是一個(gè)特殊的屬性,它的出現(xiàn)不是給開(kāi)發(fā)者用的(例如你為一個(gè)組件設(shè)置key之后,也仍無(wú)法獲取這個(gè)組件的key值),而是給react自己用的。
簡(jiǎn)單來(lái)說(shuō),react利用key來(lái)識(shí)別組件,它是一種身份標(biāo)識(shí)標(biāo)識(shí),就像我們的身份證用來(lái)辨識(shí)一個(gè)人一樣。每個(gè)key對(duì)應(yīng)一個(gè)組件,相同的key react認(rèn)為是同一個(gè)組件,這樣后續(xù)相同的key對(duì)應(yīng)組件都不會(huì)被創(chuàng)建。
key的使用場(chǎng)景
在項(xiàng)目開(kāi)發(fā)中,key屬性的使用場(chǎng)景最多的還是由數(shù)組動(dòng)態(tài)創(chuàng)建的子組件的情況,需要為每個(gè)子組件添加唯一的key屬性值。那會(huì)有的人就會(huì)自然而然想到,key和動(dòng)態(tài)渲染的子元素獲取的index位置的值很接近,那不是可以直接用index附上key的值呢key={index}?
例如:
{dataList.map((item,index)=>{ return{item.name}}) }
在你嘗試過(guò)后會(huì)發(fā)現(xiàn),報(bào)錯(cuò)沒(méi)了,渲染也沒(méi)問(wèn)題不是很正常嘛?!但是強(qiáng)烈不推薦用數(shù)組index來(lái)作為key。
如果數(shù)據(jù)更新僅僅是數(shù)組重新排序或在其中間位置插入新元素,那么視圖元素都將重新渲染。
例如:
本來(lái)index=2的元素向前移動(dòng)后,那該元素的key不也同樣發(fā)生了改變那這樣會(huì)改變的Key就沒(méi)有任何的存在意義,既然是作為“身份證”一樣的存在,那就不容有失。當(dāng)然,在你用key值創(chuàng)建子組件的時(shí)候,若數(shù)組的內(nèi)容只是作為純展示,而不涉及到數(shù)組的動(dòng)態(tài)變更,其實(shí)是可以使用index作為key的。
key的值必須保證唯一且穩(wěn)定
我在與Key值打過(guò)幾次交道過(guò)后,覺(jué)得key值就類(lèi)似于數(shù)據(jù)庫(kù)中的主鍵id一樣,有且唯一。
//this.state.users內(nèi)容。注意:李四和王五的id相同?。?! this.state = { users: [{id:1,name: '張三'}, {id:2, name: '李四'}, {id: 2, name: "王五"}], ....//省略 } render() return() );用戶(hù)列表
{this.state.users.map(u =>{u.id}:{u.name})}
注意以上范例中,動(dòng)態(tài)渲染的數(shù)據(jù)中,key以數(shù)據(jù)的id來(lái)定,而李四、王五的id相同而導(dǎo)致Key的雷同,最后的渲染結(jié)果為張三和李四,王五并沒(méi)有展示出來(lái)。主要是因?yàn)?react根據(jù)key認(rèn)為李四和王五是同一個(gè)組件(李四和王五的key值相同),導(dǎo)致第一個(gè)被渲染,后續(xù)的會(huì)被丟棄掉。
這樣,有了key屬性后,就可以與組件建立了一種對(duì)應(yīng)關(guān)系,react根據(jù)key來(lái)決定是銷(xiāo)毀重新創(chuàng)建組件還是更新組件。
并且,Key也要保證值的穩(wěn)定性,例如:
{dataList.map((item,index)=>{ return{item.name}}) }
尤其如以上范例中所示,key的值以Math.random()隨機(jī)生成而定,這使得數(shù)組元素中的每項(xiàng)都重新銷(xiāo)毀然后重新創(chuàng)建,有一定的性能開(kāi)銷(xiāo);另外可能導(dǎo)致一些意想不到的問(wèn)題出現(xiàn)。
所以,Key的值必須保證其唯一和穩(wěn)定性
所以,在不能使用random隨機(jī)生成key時(shí),我們可以像下面這樣用一個(gè)全局的localCounter變量來(lái)添加穩(wěn)定唯一的key值。
var localCounter = 1; this.data.forEach(el=>{ el.id = localCounter++; }); //向數(shù)組中動(dòng)態(tài)添加元素時(shí), function createUser(user) { return { ...user, id: localCounter++ } }
key其它注意事項(xiàng)
當(dāng)然除了為數(shù)據(jù)元素生成的組件要添加key,且key要穩(wěn)定且唯一之外,還需要注意以下幾點(diǎn):
key屬性是添加到自定義的子組件上,而不是子組件內(nèi)部的頂層的組件上。
//MyComponent ... render() {//error{{item.name}}} ... //right
key值的唯一是有范圍的,即在數(shù)組生成的同級(jí)同類(lèi)型的組件上要保持唯一,而不是所有組件的key都要保持唯一
不僅僅在數(shù)組生成組件上,其他地方也可以使用key,主要是react利用key來(lái)區(qū)分組件的,相同的key表示同一個(gè)組件,react不會(huì)重新銷(xiāo)毀創(chuàng)建組件實(shí)例,只可能更新;key不同,react會(huì)銷(xiāo)毀已有的組件實(shí)例,重新創(chuàng)建組件新的實(shí)例。
{ this.state.type ?:}
例如上面代碼中,this.state.type的值改變時(shí),原Son_1和Son2組件的實(shí)例都將會(huì)被銷(xiāo)毀,并重新創(chuàng)建Son_1和Son_2組件新的實(shí)例,不能繼承原來(lái)的狀態(tài),其實(shí)他們只是互換了位置。為了避免這種問(wèn)題,我們可以給組件加上key。
{ this.state.type ?:}
這樣,this.state.type的值改變時(shí),Son_1和Son2組件的實(shí)例沒(méi)有重新創(chuàng)建,react只是將他們互換位置。
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持創(chuàng)新互聯(lián)。