第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

跪求!react中直接修改state解構(gòu)出來的值合理嗎?怎么回事哈?。?/h1>

跪求!react中直接修改state解構(gòu)出來的值合理嗎?怎么回事哈?。?/h1>
開心每一天1111 2019-10-31 10:28:07
第一個栗子?state={name:'Sam'}fn(){const{data}=this.state;data.name='xiaobe';this.setState({data:{...data}})}沒有出現(xiàn)警告,且能實現(xiàn)效果,但這樣的做法合理嗎?第二個栗子?:使用了lodash/find,重新賦值了一個新的數(shù)組,但是原數(shù)組依舊被更改了,為什么?importfindfrom'lodash/find';state={data:[{id:1,name:'xiaobe'},{id:2,name:'Sam'}]}fn(){const{data}=this.state;constnewData=[...data];console.log('修改前data',data);constnewItem=find(newData,{id:1})||{};console.log('修改前newItem',newItem);if(Object.keys(newItem).length){newItem.name='new-xiaobe';}console.log('修改后newItem',newItem);this.setState({data:[...newData],},()=>{console.log('修改后data',data);},);}發(fā)現(xiàn),修改前data里第一條name已經(jīng)從xiaobe變成了new-xiaobe,請問為什么?
查看完整描述

2 回答

?
白板的微信

TA貢獻1883條經(jīng)驗 獲得超3個贊

在回答問題之前,先補充以下幾個知識點:
棧內(nèi)存和堆內(nèi)存?;緮?shù)據(jù)類型的數(shù)據(jù)是存在棧內(nèi)存的,而引用類型的數(shù)據(jù)則是存在堆內(nèi)存的,在棧內(nèi)存里面存放的實際是數(shù)據(jù)在堆內(nèi)存中的內(nèi)存地址。
淺拷貝和深拷貝。淺拷貝僅僅是復(fù)制了數(shù)據(jù)在棧內(nèi)存中的內(nèi)存地址,而深拷貝指在計算機中開辟了一塊新的內(nèi)存地址用于存放復(fù)制的對象。
第一個栗子:首先這樣子的寫法是沒有問題,react調(diào)度的時候會判斷oldData和newData是否相等,不相等時則更新視圖,引用類型之間的比較實際就是內(nèi)存地址的比較,如果內(nèi)存地址是一樣則判斷結(jié)果為true,不一樣則判斷結(jié)果為false。這里的{...data},相當于重新開辟了內(nèi)存地址,newData相比較oldData,內(nèi)存地址發(fā)生了改變,那么react便會知道其發(fā)生了改變,然后去更新視圖。但這種寫法并不是最好的,因為畢竟是對原數(shù)據(jù)做了修改,而this.setState又是異步的,如果在this.setState之后緊跟著依據(jù)data又做了其他相應(yīng)的操作,那么就會有問題。我個人推薦的寫法應(yīng)該是這樣子的:
state={
name:'Sam'
}
fn(){
const{data}=this.state;
this.setState({
data:{...data,name:'xiaobe'}
})
}
第二個栗子:理解這個問題的核心就是得了解[...data]到底干了啥?下面以你提供的數(shù)據(jù)來解釋以下:
為了方便理解,我改造一下data。
consta={
id:1,
name:'xiaobe'
}
constb={
id:2,
name:'Sam'
}
constdata=[a,b]
[...data]的流程如下:
constnewData=[]//newArray()
newData.push(a)
newData.push(b)
通過上面的代碼,我們發(fā)現(xiàn)如果直接判斷newData===data,結(jié)果一定為false,因為newData的內(nèi)存地址和data的不一致。但是如果你判斷newData[0]===data[0]以及newData[1]===data[1],那結(jié)果變?yōu)閠rue,子項的內(nèi)存地址并沒有發(fā)生變化。當你修改第一項的name值之后,便會影響到data和newData,因為這個子項被data和newData都引用了。
                            
查看完整回答
反對 回復(fù) 2019-10-31
  • 2 回答
  • 0 關(guān)注
  • 461 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯(lián)系客服咨詢優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動學(xué)習(xí)伙伴

公眾號

掃描二維碼
關(guān)注慕課網(wǎng)微信公眾號