網站首頁 編程語言 正文
setState異步更新
開發中當組件中的狀態發生了變化,頁面并不會重新渲染。我們必須要通過setState來告知React數據已經發生了變化,重新渲染頁面。
先來看下面的例子:
constructor() {
super();
this.state = {
message: "Hello World",
};
}
changeText() {
this.setState({
message: "Hello React",
});
console.log(this.state.message); // Hello World
}
最終打印的結果是Hello World;
可見setState是異步的操作,我們并不能在執行完setState之后立馬拿到最新的state的結果
那么為什么setState設計為異步呢?
setState設計為異步,可以顯著的提升性能
- 如果每次調用setState都進行一次更新,那么意味著render函數會被頻繁調用,界面重新渲染,這樣效率是很低的;
- 最好的辦法是獲取多個更新,之后進行批量處理;
如果同步更新了state,但是還沒有執行render函數,那么state和props不能保持同步;
state和props不能保持一致性,會在開發中產生很多的問題;(比如,組件嵌套時影響子組件中的狀態)
如何獲取異步的結果
setState的回調
setState接受兩個參數:第二個參數是一個回調函數,這個回調函數會在更新后會執行;
changeText() {
this.setState({
message: "Hello React",
},()=>{
console.log('-----',this.state.message); // Hello React
});
}
也可以在生命周期函數中獲?。?/p>
componentDidUpdate(prevProps, prevState, snapshot){
console.log(this.state.message);// Hello React
}
setState一定是異步的嗎?
React18版本之前
其實可以分成兩種情況:
- 在組件生命周期或React合成事件中,setState是異步的;
- 在setTimeout或者原生DOM事件中,setState是同步的
驗證一:在setTimeout中的更新:
setTimeout(() => {
this.setState({
message: "Hello React",
});
console.log(this.state.message); // Hello React
}, 0);
驗證二:原生DOM事件:
componentDidMount() {
const btnEl = document.querySelector("#btn");
btnEl.addEventListener("click", () => {
this.setState({
message: "Hello React",
});
console.log(this.state.message); // Hello React
});
}
React18版本之后
setState默認是異步的
- 在React18之后,默認所有的操作都被放到了批處理中(異步處理)
如果希望代碼可以同步拿到,則需要執行特殊的flushSync操作:
import { flushSync } from "react-dom";
changeText() {
flushSync(() => {
this.setState({
message: "Hello React",
});
});
console.log(this.state.message); // Hello React
}
原文鏈接:https://juejin.cn/post/7165867331418062862
相關推薦
- 2023-02-12 Jupyter?Notebook讀取csv文件出現的問題及解決_python
- 2023-10-16 清理linux日志
- 2022-07-21 python實現利用stack對輸入的式子進行計算算法
- 2021-12-02 Golang共享變量如何解決問題_Golang
- 2023-03-27 詳解C/C++高精度(加減乘除)算法中的壓位優化_C 語言
- 2022-11-16 通用?HTTP?簽名組件的另類實現方式_實用技巧
- 2022-12-06 Python實現批量修改xml文件的腳本_python
- 2023-05-07 numpy.concatenate函數用法詳解_python
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支