react的setState使用詳解

react修改狀態(tài)是不能直接修改的,需要使用setState來進行狀態(tài)的修改,但是setState的使用會存在一些問題。覺得有必要在此做一下總結(jié)。。。。

setState()不是立刻更新組件。其可能是批處理或推遲更新。這使得在調(diào)用setState()后立刻讀取this.state的一個潛在陷阱。

就像這樣:

incrementCount() {
  this.setState({count: this.state.count + 1});
}
handleSomething() {
  this.incrementCount();
  this.incrementCount();
  this.incrementCount();
}
調(diào)用了3次incrementCount方法, 期望this.state.count的值是3, 但最后卻是1

本質(zhì)上setState修改state的值是通過淺合并把新的值合并到state的對象上,如果多次修改,react會進行批次處理

類似于:

Object.assign(
  previousState,
  {count: state.count + 1},
  {count: state.count + 1},
  {count: state.count + 1},
)
之后的調(diào)用在同一周期中將會重寫之前調(diào)用的值,因此數(shù)量僅會被加一。若之后的狀態(tài)依賴于之前的狀態(tài),

解決這個問題的方式:

componentDidUpdate或一個setState回調(diào)(setState(updater, callback))

  1. 當(dāng)中的每個方法都會保證在更新被應(yīng)用之后觸發(fā)
  2. updater函數(shù)接收到的prevState 和 props保證都是最新的
incrementCount() {
  this.setState((state) => {
    return {count: state.count + 1}
  });
}
handleSomething() {
  this.incrementCount();
  this.incrementCount();
  this.incrementCount();
}

setState什么時候會異步更新

setState的執(zhí)行流程:

this.setState(newState)
==>
newState存入pending隊列
==>
判斷是否處于batch update
==>
如果是的話就保存組件月dirtyComponents中,
如果不是的話就遍歷所有的dirtyComponents,調(diào)用updateComponent,更新pending state or props

在 React 的 setState 函數(shù)實現(xiàn)中,會根據(jù)一個變量 isBatchingUpdates 判斷是直接更新 this.state 還是放到隊列中回頭再說,
而 isBatchingUpdates 默認是 false,也就表示 setState 會同步更新 this.state,
但是,有一個函數(shù) batchedUpdates,這個函數(shù)會把 isBatchingUpdates 修改為 true,
而當(dāng) React 在調(diào)用事件處理函數(shù)之前就會調(diào)用這個 batchedUpdates,造成的后果,就是由 React 控制的事件處理過程 setState 不會同步更新 this.state。

  • setState會導(dǎo)致re-rederning, 而re-rederning的代價是昂貴的, 所以他們會盡可能的把多次操作合并成一次提交。
  • 因為當(dāng)傳入的是一個函數(shù)時,state讀取的是pending隊列中state的值

setState什么時候會異步更新, 什么時候會同步更新

React是根據(jù)isBatchingUpdates來合并更新的, 那么當(dāng)調(diào)用setState的方法或者函數(shù)不是由React控制的話, setState自然就是同步更新了。

  1. 如componentDidMount等生命周期以及React的事件即為異步更新,這里不顯示具體代碼。
  2. 如自定義的瀏覽器事件,setTimeout,setInterval等脫離React控制的方法, 即為同步更新
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容