繁体   English   中英

Function 未使用挂钩指向 state 变量的更新值

[英]Function not pointing to the updated value of state variable using hooks

我目前正在重构一个从 setState 到 hooks 的 React 应用程序。 我不明白为什么 state 变量没有改变。 这是一个例子:

import React, { useState, useEffect } from 'react';

function Hook() {
    const [num, setNum] = useState(1);

    useEffect(() => {
        window.addEventListener("mousemove", logNum);
    }, []);

    const logNum = () => {
        console.log(num);
    }
    const handleToggle = () => {
        if (num == 1) {
            console.log('setting num to 2');
            setNum(2);
        } else {
            console.log('setting num to 1');
            setNum(1);
        }
    }

    return (
        <div>
            <button onClick={handleToggle}>TOGGLE BOOL</button>
        </div>
    );
}
export default Hook;

当我点击按钮时,我期待 output 是这样的:

// 1
// setting num to 2
// 2
// setting num to 1
// 1

但是 output 看起来像这样:

在此处输入图像描述

为什么没有记录更新的 num 变量? logNum() function 不应该总是指向 state 的当前值吗?

这就是为什么效果依赖性必须是详尽无遗的。 不要在依赖关系上撒谎

logNumnum上关闭,因此在每次重新渲染时都有一个包含新值的新num变量,以及一个记录该值的新logNum function。 然而,您的效果只被初始化一次,因此它只知道第一个logNum 因此,您必须添加logNum作为依赖项,以便在numlogNum发生变化时更新效果:

 useEffect(() => {
    window.addEventListener("mousemove", logNum);
}, [logNum]);

您会注意到您的效果没有正确清理,您也应该添加一个removeEventListener

    return () => window.removeEventListener("mousemove", logNum);

现在,如果您调试这段代码,您会注意到效果会在每次重新渲染时触发。 这是因为在每次重新渲染时都会创建一个新的logNum function,无论num是否发生变化。 为防止这种情况,您可以使用useCallback使logNum引用稳定:

  const logNum = useCallback(() => console.log(num), [num]);

所有这些的替代方法是使用对当前 state的引用:

  const actualNum = useRef(num);

    // that works no matter when and how this is executed
    console.log(actualNum.current);

暂无
暂无

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

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