關(guān)于react useState更新異步問(wèn)題
react useState更新異步
當(dāng)我們使用react中useState這個(gè)hook時(shí)候,如下
const [page, setPage] = useState(1); const handlerClick = (e)=>{ ?? ?setPage(e.current); ?? ?console.log(page); }
當(dāng)我打印page時(shí)候,此時(shí)page還是1,因?yàn)閡seState的更新是異步的,這和react的機(jī)制有關(guān),要解決這個(gè)可以這樣做
1.使用useState的返回值
?setPage(e.current); ? ? ? ? setPage(prevFoo => { ? ? ? ? ? ? console.log('page===========',prevFoo);//page=========== 2 ? ? ? ? ? ? return prevFoo; ?});
2.自定義hook(第一種方式)
? ? const useSyncCallback = callback => { ? ? ? ? const [proxyState, setProxyState] = useState({ current: false }); ? ? ? ? const Func = useCallback(() => { ? ? ? ? ? setProxyState({ current: true }); ? ? ? ? }, [proxyState]); ? ? ? ? useEffect(() => { ? ? ? ? ? if (proxyState.current === true) { ? ? ? ? ? ? setProxyState({ current: false }); ? ? ? ? ? } ? ? ? ? }, [proxyState]); ? ? ? ? useEffect(() => { ? ? ? ? ? proxyState.current && callback(); ? ? ? ? }); ? ? ? ? return Func; ? ? ? }; ? ? ? const funcqq = useSyncCallback(() => { ? ? ? ? console.log('page===========',page);//page=========== 2 ? ? ? }); //調(diào)用 setPage(e.current); funcqq()
自定義hook(第二種方式)
function useCurrentValue(value) { ? ? const ref = useRef(value); ? ? useEffect(() => { ? ? ? ref.current = value; ? ? }, [value]); ? ? return ref; } //調(diào)用 ?const log = () => { ? ? setCount(count + 1); ? ? setTimeout(() => { ? ? ? console.log(currentCount.current); ? ? }, 3000); ? };
3.使用useRef替代useState,第三種方式在自定義hook第二種方式里面已經(jīng)體現(xiàn)了
4.使用useEffect,在自定義hook第二種方式里面已經(jīng)體現(xiàn)了
記useState異步更新小坑
問(wèn)題:
在hooks中,修改狀態(tài)的是通過(guò)useState返回的修改函數(shù)實(shí)現(xiàn)的.它的功能類似于class組件中的this.setState().而且,這兩種方式都是異步的.可是this.setState()是有回調(diào)函數(shù)的,那useState()呢?
問(wèn)題點(diǎn)
它異步且沒(méi)有回調(diào)函數(shù)
const [count,setCount] = useState(1) useEffect(()=> { setCount(2,()=>{ console.log('測(cè)試hooks的回調(diào)'); }) console.log(count); },[])
可以看到提示 “State updates from the useState() and useReducer() Hooks don’t support the second callback argument. To execute a side effect after rendering, declare it in the component body with useEffect().”
是不支持回調(diào)函數(shù)的形式的。因?yàn)閟etCount是異步的,所以打印count是在改變count之前的。
如果我們想要在打印的時(shí)候就拿到最新的值,那么我們可以通過(guò)setCount的第二個(gè)參數(shù)指定依賴項(xiàng)
const [count,setCount] = useState(1) useEffect(()=> { setCount(2) console.log(count); },[count])
當(dāng)count發(fā)生變化的時(shí)候,useEffect就會(huì)再次相應(yīng),但是這樣就會(huì)有個(gè)問(wèn)題,當(dāng)count從1變?yōu)?的時(shí)候useEffect的回調(diào)函數(shù)會(huì)再次執(zhí)行,就會(huì)分別打印1,2兩次。
useEffect(()=> { let currentValue = null setCount((preVal)=>{ currentValue=preVal return 2 }) if(currentValue!==count){ console.log(count); } },[count])
通過(guò)添加判斷條件,我們可以讓想要執(zhí)行的代碼只執(zhí)行一次
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
react學(xué)習(xí)每天一個(gè)hooks?useWhyDidYouUpdate
這篇文章主要為大家介紹了react學(xué)習(xí)每天一個(gè)hooks?useWhyDidYouUpdate使用示例解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-04-04一篇文章介紹redux、react-redux、redux-saga總結(jié)
這篇文章主要介紹了一篇文章介紹redux、react-redux、redux-saga總結(jié),小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2019-05-05React + webpack 環(huán)境配置的方法步驟
本篇文章主要介紹了React + webpack 環(huán)境配置的方法步驟,詳解的介紹了開(kāi)發(fā)環(huán)境的配置搭建,有興趣的可以了解一下2017-09-09React父子組件傳值(組件通信)的實(shí)現(xiàn)方法
本文主要介紹了React父子組件傳值(組件通信)的實(shí)現(xiàn)方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2022-05-05