日本免费高清视频-国产福利视频导航-黄色在线播放国产-天天操天天操天天操天天操|www.shdianci.com

學無先后,達者為師

網站首頁 編程語言 正文

解決react中useState狀態異步更新的問題_React

作者:Melody_lw ? 更新時間: 2022-08-27 編程語言

疑惑

相信剛開始使用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有:useEffectPromise

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

欄目分類
最近更新