立即获取hook更新的值


自定义hook — 立即获得setState之后的值

通常我们在一个函数中使用useState的第二个参数,也就是dispatch 更新state,

在这个setState 的下面我们 log 看看的话,

就会发现我们拿不到我们刚刚才 set 的值,

在刚刚set完调用的函数里,也拿不到最新的值。

const numberChange = (val: number) => {
    console.log('pack', pack) // 拿不到最新的值,是因为函数和log 一样,也是同步执行的。
    setNum(val); 
    getSyncPack(val); //1 传参
};

useEffect(() => {
    const fn = async () => {
        const result = await axios.get('/../../../list'); // 接口地址
        console.warn('result', result);
        const positions = result.data.data[0];
        positions && setPack(positions);

        numberChange(1);
    };
    fn();
}, []);


这是 react 的规则所决定的,此时尚在前一轮的渲染中。

-----------------------------------------

react 每次渲染都有独立的state和函数,

拿不到最新值,是因为我们在过去的渲染函数中!

因此也只能获得那一次渲染中的state。
/**
 * @FilePath: hooks/useSyncCallback
 * @Author: lixiaofei
 */

// 在组件中调用此函数,可以立即获得刚刚set 完最新的值,同时支持传参的方式。
import {useState, useEffect, useCallback} from 'react';

const useSyncCallback = <T>(callback: (value?: T) => void) => {
    const [proxyState, setProxyState] = useState({current: false});
    const [paramsters, setParamsters] = useState<T>();

    const Func = useCallback((val: T) => {
        setParamsters(val);
        setProxyState({current: true});
    }, []);

    useEffect(() => {
        if (proxyState.current === true) {
            setProxyState({current: false});
        }
    }, [proxyState]);

    useEffect(() => {
        proxyState.current && callback(paramsters);
    });

    return Func;
};

export default useSyncCallback;
// 组件中使用
....
...
const [pack, setPack] = useState<any>({});

const getSyncPack = useSyncCallback<number>(val => { // val 传递的参数
    console.warn('val', val);
    // 在这个函数内部可以 log 到最新的值
    // 这里是为了实时获得首次 effect 从接口获取的 pack的对象属性
    if (val) {
        const newList: SwitchList[] = [];
        for (let i = 0; i < val; i++) {
            newList.push({
                label: `位置${i + 1}: `,
                inpVal: pack[`position${i + 1}`],
                swiVal: pack[`position${i + 1}Enable`],
            });
        }
        setList(newList);
    }
});

const numberChange = (val: number) => {
    setNum(val); 
    getSyncPack(val); //1 传参
};

文章作者: KarlFranz
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 reprint policy. If reproduced, please indicate source KarlFranz !
评论
  目录