React?setState是異步還是同步原理解析
setState異步更新
開(kāi)發(fā)中當(dāng)組件中的狀態(tài)發(fā)生了變化,頁(yè)面并不會(huì)重新渲染。我們必須要通過(guò)setState來(lái)告知React數(shù)據(jù)已經(jīng)發(fā)生了變化,重新渲染頁(yè)面。
先來(lái)看下面的例子:
constructor() {
super();
this.state = {
message: "Hello World",
};
}
changeText() {
this.setState({
message: "Hello React",
});
console.log(this.state.message); // Hello World
}
最終打印的結(jié)果是Hello World;
可見(jiàn)setState是異步的操作,我們并不能在執(zhí)行完setState之后立馬拿到最新的state的結(jié)果
那么為什么setState設(shè)計(jì)為異步呢?
setState設(shè)計(jì)為異步,可以顯著的提升性能
- 如果每次調(diào)用setState都進(jìn)行一次更新,那么意味著render函數(shù)會(huì)被頻繁調(diào)用,界面重新渲染,這樣效率是很低的;
- 最好的辦法是獲取多個(gè)更新,之后進(jìn)行批量處理;
如果同步更新了state,但是還沒(méi)有執(zhí)行render函數(shù),那么state和props不能保持同步;
state和props不能保持一致性,會(huì)在開(kāi)發(fā)中產(chǎn)生很多的問(wèn)題;(比如,組件嵌套時(shí)影響子組件中的狀態(tài))
如何獲取異步的結(jié)果
setState的回調(diào)
setState接受兩個(gè)參數(shù):第二個(gè)參數(shù)是一個(gè)回調(diào)函數(shù),這個(gè)回調(diào)函數(shù)會(huì)在更新后會(huì)執(zhí)行;
changeText() {
this.setState({
message: "Hello React",
},()=>{
console.log('-----',this.state.message); // Hello React
});
}
也可以在生命周期函數(shù)中獲?。?/p>
componentDidUpdate(prevProps, prevState, snapshot){
console.log(this.state.message);// Hello React
}
setState一定是異步的嗎?
React18版本之前
其實(shí)可以分成兩種情況:
- 在組件生命周期或React合成事件中,setState是異步的;
- 在setTimeout或者原生DOM事件中,setState是同步的
驗(yàn)證一:在setTimeout中的更新:
setTimeout(() => {
this.setState({
message: "Hello React",
});
console.log(this.state.message); // Hello React
}, 0);
驗(yàn)證二:原生DOM事件:
componentDidMount() {
const btnEl = document.querySelector("#btn");
btnEl.addEventListener("click", () => {
this.setState({
message: "Hello React",
});
console.log(this.state.message); // Hello React
});
}
React18版本之后
setState默認(rèn)是異步的
- 在React18之后,默認(rèn)所有的操作都被放到了批處理中(異步處理)

如果希望代碼可以同步拿到,則需要執(zhí)行特殊的flushSync操作:
import { flushSync } from "react-dom";
changeText() {
flushSync(() => {
this.setState({
message: "Hello React",
});
});
console.log(this.state.message); // Hello React
}以上就是React setState是異步還是同步原理解析的詳細(xì)內(nèi)容,更多關(guān)于React setState異步同步的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
關(guān)于react-router-dom路由入門(mén)教程
這篇文章主要介紹了關(guān)于react-router-dom路由入門(mén)教程,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-03-03
react高階組件經(jīng)典應(yīng)用之權(quán)限控制詳解
在React中,高階組件是重用組件邏輯的一項(xiàng)高級(jí)技術(shù)。下面這篇文章主要給大家介紹了關(guān)于react高階組件經(jīng)典應(yīng)用之權(quán)限控制的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧。2017-09-09
React-Native TextInput組件詳解及實(shí)例代碼
這篇文章主要介紹了React-Native TextInput組件詳解及實(shí)例代碼的相關(guān)資料,需要的朋友可以參考下2016-10-10
reset.css瀏覽器默認(rèn)樣式表重置(user?agent?stylesheet)的示例代碼
這篇文章主要介紹了reset.css瀏覽器默認(rèn)樣式表重置(user?agent?stylesheet),本文通過(guò)示例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2023-12-12
從零開(kāi)始搭建一個(gè)react項(xiàng)目開(kāi)發(fā)
這篇文章主要介紹了從零開(kāi)始搭建一個(gè)react項(xiàng)目開(kāi)發(fā),小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-02-02
React中的stopPropagation和preventDefault實(shí)踐記錄
本文詳細(xì)介紹了事件冒泡、捕獲與React合成事件體系下的表現(xiàn)區(qū)別,包括事件傳播階段、處理方式、事件池機(jī)制等核心概念,對(duì)React?stopPropagation和preventDefault相關(guān)知識(shí)感興趣的朋友跟隨小編一起看看吧2025-11-11
React中使用Axios進(jìn)行HTTP請(qǐng)求
這篇文章主要為大家展示了如何在 React 中使用 Axios 進(jìn)行 HTTP 請(qǐng)求,包括 GET 和 POST 請(qǐng)求的使用,感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2024-11-11
react實(shí)現(xiàn)Radio組件的示例代碼
這篇文章主要介紹了react實(shí)現(xiàn)Radio組件的示例代碼,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2021-04-04

