繁体   English   中英

react如何在useCallback中保持变量值?

[英]How does react keep variables value in useCallback?

const { useState, useCallback } = React;
let globalValue = 0;
const ComponentA = ({ propValue }) => {
    const [sum, setSum] = useState(propValue);
    const [stateValue, setStateValue] = useState(0);
    const onClick = useCallback(() => {
        console.log(propValue, stateValue, globalValue);
        setSum(propValue + stateValue + globalValue);
    }, []);
    return (
        <div>
            <p>State value is {stateValue}</p>
            <p>Sum is {sum}</p>
            <button onClick={() => setStateValue(stateValue + 1)}>
                Set stateValue
              </button>
            <button onClick={() => globalValue += 1}>
                Set globalValue
            </button>
            <button onClick={onClick}>
                Get Sum
            </button>
        </div>
    );
};
const Parent = () => {
    const [propValue, setPropValue] = useState(0);

    return (
        <div>
            <p>Prop value is {propValue}</p>
            <button onClick={() => setPropValue(propValue + 1)}>
                Set PropValue
            </button>
            <ComponentA propValue={propValue} />
        </div>
    );
};

如果ComponentAuseCallback的依赖列表设置为[] ,则执行console.log时,无论当前的propValuestateValue是什么,它们都将始终为0 但是globalValue将始终使用最新的。 当我检查propValuestateValue__proto__时,它们都只是原始类型。

useCallback钩子如何保持变量的原始值? 它不应该遵守这样的规则,即如果当前 scope 中未定义变量,它将查找其父级并使用那里的值(如globalValue )?

我知道这是useCallback/useMemo的重点,但这是如何实现的?

我从这个博客https://dmitripavlutin.com/react-hooks-stale-closures/找到了答案

这是useCallback的模拟代码。

(function () {
    const ReactDomTree = {};
    const memo = {};
    const getButtonElement = () => { return ReactDomTree.buttonA };
    function useMemo(create) {
        if (!memo.result) {
            memo.result = create();
        }

        return memo.result;
    };

    const useCallback = function (callback) {
        return useMemo(() => callback);
    }


    function component() {
        let propValue = Math.floor(Math.random() * 100); // mimic prop update
        let stateValue = Math.floor(Math.random() * 100); // mimic state update
        console.log('component render', propValue, stateValue);

        const onClick = useCallback(() => {
            console.log('onclick', propValue, stateValue);
        });

        if (!ReactDomTree.buttonA) {
            ReactDomTree.buttonA = {};
            ReactDomTree.buttonA.onClick = onClick;
        }
    }

    component(); // component render
    let button = getButtonElement()
    button.onClick();
    component(); // component render
    button = getButtonElement()
    button.onClick() // This log result is same as the previous one

})();

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM