gpt4 book ai didi

javascript - 函数未使用钩子(Hook)指向状态变量的更新值

转载 作者:行者123 更新时间:2023-12-04 10:13:44 24 4
gpt4 key购买 nike

我目前正在将一个 react 应用程序从 setState 重构为钩子(Hook)。我不明白为什么状态变量没有改变。这是一个例子:

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;

当我单击按钮时,我期望输出类似于:
// 1
// setting num to 2
// 2
// setting num to 1
// 1

但输出看起来像这样:

enter image description here

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

最佳答案

这就是为什么效果依赖必须是详尽的。 Don't lie about dependencies .
logNum关闭num ,所以每次重新渲染都会有一个新的 num包含新值的变量和新的 logNum记录该值的函数。然而,你的效果只被初始化一次,因此它只知道第一个 logNum .因此,您必须添加 logNum作为一个依赖,所以效果会在任何时候更新 num因此logNum变化:

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

你会注意到你的效果不正确 clean up , 你应该添加一个 removeEventListener也。
    return () => window.removeEventListener("mousemove", logNum);

现在,如果您调试这段代码,您会注意到效果会在每次重新渲染时触发。那是因为一个新的 logNum无论是否 num,每次重新渲染都会创建函数改变与否。为了防止这种情况,您可以使用 useCallback 制作 logNum引用稳定:
  const logNum = useCallback(() => console.log(num), [num]);

所有这些的替代方法是使用对 current state 的引用。 :
  const actualNum = useRef(num);

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

关于javascript - 函数未使用钩子(Hook)指向状态变量的更新值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61184109/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com