網站首頁 編程語言 正文
疑惑
相信剛開始使用react
函數組件的小伙伴也遇到過一個坑,就是 useState
更新狀態是異步更新的,但是react
并沒有提供關于這個問題的解決方案。那我們能否使用自己的方法來解決這個問題呢?答案肯定是可以的。
狀態異步更新帶來的問題
就拿一個比較常見的場景來說。在react項目中,我們想在關閉對話框后再去處理其他業務。但是 useState
的狀態是異步更新的。我們通過setVisible
更新狀態后,狀態并沒有立馬更新,這也就說明對話框并沒有關閉,這也就造成了我們后面的邏輯在對話框沒關閉時就執行了,這并不是我們想要的結果。下面來看我是如何來巧妙的解決這個問題的。
問題示例
// App.tsx import {useState} from "react" export default ()=>{ const [num,setNum]=useState(0) const add=()=>{ console.log("更新前",num) setNum(num+1) console.log('更新后',num) } return( <div className='App'> <p>{num}</p> <button onClick={add}>num++</button> </div> ) }
下面是上面組件運行結果:
點擊按鈕后的運行結果:
當我們點擊按鈕時的打印結果:
問題解決
類組件的解決方案
在類組件中,我們可以在 setState(newstate,callback)
第二個參數傳一個回調來處理本次狀態更新后的一些其他業務。但是在函數組件中我們如何來解決這個問題呢?來看以下方案,也是我們這篇文章主要想為大家解決的問題。
函數組件的解決方案
解決該問題使用到的 api
有:useEffect
,Promise
1.在項目源碼目錄下創建文件夾 customHooks
,然后在 customHooks/useCallbackState.ts
中編寫如下代碼:
import { useState, useRef, useEffect } from 'react'; export default(initState: any)=>{ const stateRef = useRef(null as any); const [state, setState] = useState(initState); useEffect(() => { stateRef.current && stateRef.current(state); }, [state]); return [ state, (newState:typeof initState):Promise<typeof initState>=> new Promise(rel=>{stateRef.current=rel;setState(newState)}) ]; }
2.在上面的 App.tsx
中使用上面的自定義hook
import useCallbackState from "@/customHooks/useCallbackState" const [num,setNum]=useCallbackState(0) const add=()=>{ console.log('更新前',num) setNum(num+1) .then((newNum:any)=>{ console.log('更新后',newNum) // console.log(num) }) }
此時的運行結果如下:
注意:謹慎使用,打印可以看出,其實狀態并沒有真正完成更新。依然達不到類組件callback的效果。
其他解決方案
如果真的存在上面這種需求,我們可以使用類組件,或者使用 setTimeout
來解決上面的問題,把對話框關閉后的業務寫在延時的回調中就行了,延時個 500 毫秒 狀態一定更新完畢了,個人感覺這個方法不太好,還是推薦使用類組件來解決上述問題。
結尾
原文鏈接:https://blog.csdn.net/qq_61233877/article/details/124017052
相關推薦
- 2022-07-21 nginx的配置優化及經常使用的超時配置說明
- 2022-04-08 c++11中std::move函數的使用_C 語言
- 2022-12-19 C++?Boost?Coroutine使用協程詳解_C 語言
- 2022-07-15 Python中五種實現字符串反轉的方法_python
- 2022-07-08 C語言算法學習之雙向鏈表詳解_C 語言
- 2023-05-16 python實現動態規劃算法的示例代碼_python
- 2023-02-26 詳解flutter如何實現局部導航管理_Android
- 2024-03-21 SpringBoot +MyBatis批量插入數據
- 最近更新
-
- 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同步修改后的遠程分支