React 突變狀態(tài)
? 剛開(kāi)始開(kāi)發(fā)時(shí),我們可能會(huì)遇到這樣的問(wèn)題,使用useState創(chuàng)建對(duì)象或者數(shù)組時(shí),setState時(shí),頁(yè)面未進(jìn)行更新。這里其實(shí)是一個(gè)突變狀態(tài)的問(wèn)題
-
什么是突變狀態(tài)?
? 當(dāng)我們給
setState
一個(gè)基本數(shù)據(jù)類型時(shí),state
值將會(huì)是一個(gè)不可變的值? 更新時(shí),
state
的原始值也不會(huì)被更改,而是重新創(chuàng)建一個(gè)不可變的的基本數(shù)據(jù)類型,以觸發(fā)重新渲染 -
為什么React不推薦突變狀態(tài)?
-
調(diào)試:如果你使用
console.log
并且不改變狀態(tài),你過(guò)去的日志將不會(huì)被最近的狀態(tài)破壞修改,你可以清楚的看到渲染之間的狀態(tài)變化 -
優(yōu)化:如果之前的
props
和state
和下一個(gè)狀態(tài)相同,常見(jiàn)的react
優(yōu)化策略將會(huì)跳過(guò)本次渲染,如果你從不改變狀態(tài),檢查變化就會(huì)非常的快,如果prevProps === props
,react就可以確定它內(nèi)部并沒(méi)有發(fā)生變化 -
新功能:react正在構(gòu)建的新功能依賴將狀態(tài)視為快照,如果你正在更新過(guò)去的狀態(tài)版本,這會(huì)導(dǎo)致無(wú)法使用新功能
-
需求變更:一些需要撤銷/重做和顯示歷史記錄的值,在沒(méi)有突變的情況下更容易執(zhí)行,這是因?yàn)槟憧梢詫⑦^(guò)去的值保存在副本中,并在適用的情況下重做他們
-
更簡(jiǎn)單的實(shí)現(xiàn):因?yàn)?code>react不依賴突變,所以它不需要對(duì)你的對(duì)象做任何處理,不需要劫持你的對(duì)象??偸菍⑺鼈儼b到代理中,或者在初始化時(shí)像許多“反應(yīng)式”解決方案那樣做其他工作。這也是為什么
react
允許您將任何對(duì)象置于狀態(tài)(無(wú)論有多大)而沒(méi)有額外的性能或正確性陷阱。
-
-
如何更合理的更新對(duì)象或者數(shù)組
看這樣一段代碼:
import React from "react"; import ShoppingList from './ShoppingList'; import NewItemForm from './NewItemForm'; function App({ const [items,setItems] = React.usestateC['apple','banana']); function handleAddItem(value) { items.push(value); setItems(items); } return ( <div> {items.length > 0 && <ShoppingList items={items}/>} <NewItemForm handleAddItem={handleAddItem}/> </div> ) } export default App;
? 每當(dāng)增加一個(gè)新項(xiàng)目時(shí),
handleAddItem
函數(shù)就會(huì)被調(diào)用。但是,它并不起作用!當(dāng)我們輸入一個(gè)項(xiàng)目并提交表單時(shí),該項(xiàng)目沒(méi)有被添加到購(gòu)物清單中。? 問(wèn)題就在于我們違反了
React
中最核心的原則 —— 不可變狀態(tài)。React依靠一個(gè)狀態(tài)變量的地址來(lái)判斷狀態(tài)是否發(fā)生了變化。當(dāng)我們把一個(gè)項(xiàng)目推入一個(gè)數(shù)組時(shí),我們并沒(méi)有改變?cè)摂?shù)組的地址,所以React
無(wú)法判斷該值已經(jīng)改變。從技術(shù)上講可以改變對(duì)象或者數(shù)組本身的內(nèi)容,我們將其稱之為突變,然而,react
的狀態(tài)在技術(shù)上是可變的,但react
仍然推薦使用不可變的方式去改變react
的狀態(tài)。像基本數(shù)據(jù)類型一樣,去始終替換他們,而不是去改變他們正確的做法:
function handleAddItem(value) { const nextItems = [...items, value]; setItems(nextItems); }
? 不建議修改一個(gè)現(xiàn)有的數(shù)組,而是從頭開(kāi)始創(chuàng)建一個(gè)新的數(shù)組。這里的區(qū)別在于編輯一個(gè)現(xiàn)有的數(shù)組和創(chuàng)建一個(gè)新的數(shù)組之間的區(qū)別。文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-502373.html
? 同樣的,對(duì)于對(duì)象類型的數(shù)據(jù)也是:文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-502373.html
// ? 不建議 function handleChangeEmail(nextEmail) { user.email = nextEmail; setUser(user); } // ? 推薦 function handleChangeEmail(email) { const nextUser = { ...user, email: nextEmail }; setUser(nextUser); }
到了這里,關(guān)于React突變狀態(tài),更新數(shù)據(jù)(對(duì)象或者數(shù)組),頁(yè)面數(shù)據(jù)不刷新的問(wèn)題的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!