解決react中useState狀態(tài)異步更新的問題
疑惑
相信剛開始使用react函數(shù)組件的小伙伴也遇到過一個坑,就是 useState 更新狀態(tài)是異步更新的,但是react 并沒有提供關(guān)于這個問題的解決方案。那我們能否使用自己的方法來解決這個問題呢?答案肯定是可以的。
狀態(tài)異步更新帶來的問題
就拿一個比較常見的場景來說。在react項目中,我們想在關(guān)閉對話框后再去處理其他業(yè)務(wù)。但是 useState 的狀態(tài)是異步更新的。我們通過setVisible 更新狀態(tài)后,狀態(tài)并沒有立馬更新,這也就說明對話框并沒有關(guān)閉,這也就造成了我們后面的邏輯在對話框沒關(guān)閉時就執(zhí)行了,這并不是我們想要的結(jié)果。下面來看我是如何來巧妙的解決這個問題的。
問題示例
// 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>
)
}
下面是上面組件運行結(jié)果:

點擊按鈕后的運行結(jié)果:

當(dāng)我們點擊按鈕時的打印結(jié)果:

問題解決
類組件的解決方案
在類組件中,我們可以在 setState(newstate,callback) 第二個參數(shù)傳一個回調(diào)來處理本次狀態(tài)更新后的一些其他業(yè)務(wù)。但是在函數(shù)組件中我們?nèi)绾蝸斫鉀Q這個問題呢?來看以下方案,也是我們這篇文章主要想為大家解決的問題。
函數(shù)組件的解決方案
解決該問題使用到的 api有:useEffect,Promise
1.在項目源碼目錄下創(chuàng)建文件夾 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)
})
}
此時的運行結(jié)果如下:

注意:謹(jǐn)慎使用,打印可以看出,其實狀態(tài)并沒有真正完成更新。依然達(dá)不到類組件callback的效果。
其他解決方案
如果真的存在上面這種需求,我們可以使用類組件,或者使用 setTimeout來解決上面的問題,把對話框關(guān)閉后的業(yè)務(wù)寫在延時的回調(diào)中就行了,延時個 500 毫秒 狀態(tài)一定更新完畢了,個人感覺這個方法不太好,還是推薦使用類組件來解決上述問題。
結(jié)尾
到此這篇關(guān)于解決react中useState狀態(tài)異步更新的問題的文章就介紹到這了,更多相關(guān)react useState狀態(tài)異步更新內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
在create-react-app中使用css modules的示例代碼
這篇文章主要介紹了在create-react-app中使用css modules的示例代碼,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2018-07-07
React學(xué)習(xí)之JSX與react事件實例分析
這篇文章主要介紹了React學(xué)習(xí)之JSX與react事件,結(jié)合實例形式分析了React中JSX表達(dá)式、屬性、嵌套與react事件相關(guān)使用技巧,需要的朋友可以參考下2020-01-01
react-native使用leanclound消息推送的方法
這篇文章主要介紹了react-native使用leanclound消息推送的方法,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2018-08-08

