setState的理解和用法


1.setState更新狀態的兩種寫法:

 (1). setState(stateChange, [callback])------對象式的setState 1.stateChange為狀態改變對象(該對象可以體現出狀態的更改) 2.callback是可選的回調函數, 它在狀態更新完畢、界面也更新后(render調用后)才被調用 (2). setState(updater, [callback])------函數式的setState 1.updater為返回stateChange對象的函數。 2.updater可以接收到state和props。 4.callback是可選的回調函數, 它在狀態更新、界面也更新后(render調用后)才被調用。 總結: 1.對象式的setState是函數式的setState的簡寫方式(語法糖) 2.使用原則: (1).如果新狀態不依賴於原狀態 ===> 使用對象方式 例如: this.setState({msg:"我是修改后的值"}) (2).如果新狀態依賴於原狀態 ===> 使用函數方式 this.setState(state => ({count:state.count+1})) (3).如果需要在setState()執行后獲取最新的狀態數據, 要在第二個callback函數中讀取

2.setState 是同步更新還是異步更新

setState 並不是單純同步/異步的,它的表現會因調用的場景不同而不同:在React鈎子函數及合成事件中,它表現為異步;而在setTimeOut,setInterval等函數中,包括在DOM原生事件中,它都表現為同步。這種差異,本質上是由React事務機制和批量更新機制的工作方式來決定的。

 

在源碼中通過isBatchingUpdates 來判斷setState是先存進state隊列還是直接更新,如果值為true則執行異步操作,為false則直接更新。

那什么情況下 isBatchingUpdates 會為 true 呢?

· 在 React 可以控制的地方,isBatchingUpdates就為 true,比如在 React 生命周期事件和合成事件中,都會走合並操作,延遲更新的策略。

· 在 React 無法控制的地方,比如原生事件,具體就是在 addEventListener 、setTimeout、setInterval 等事件中,就只能同步更新。

 

一般認為,做異步設計是為了性能優化、減少渲染次數,React 團隊還補充了兩點:

· 保持內部一致性。如果將 state 改為同步更新,那盡管 state 的更新是同步的,但是 props不是。 · 啟用並發更新,完成異步渲染。

 

3.如何將同步獲取setState處理過后的值呢?

1)可以在回調函數中獲取setState處理過后的值。

 add = ()=>{ // this.setState(state => ({count:state.count+1}))
        this.setState((preState)=>{ return {count:++preState.count} },()=>{//此時setState異步執行
            console.log(this.state.count)//1
 }) }

 

2) 可以使用es6中的async await 來實現同步。

 add = async ()=>{ await this.setState(state => ({count:state.count+1})) console.log(this.state.count)//1
    }

 

3)可以使用setTimeout、setInterval

 add =  ()=>{ setTimeout(()=>{ this.setState(state => ({count:state.count+1})) console.log(this.state.count)//1
        },0) }

 

注意:如果強行使用同步,就會每次改變狀態都會重新render渲染,這樣性能就會降低。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM