[英]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 的当前值吗?
这就是为什么效果依赖性必须是详尽无遗的。 不要在依赖关系上撒谎。
logNum
在num
上关闭,因此在每次重新渲染时都有一个包含新值的新num
变量,以及一个记录该值的新logNum
function。 然而,您的效果只被初始化一次,因此它只知道第一个logNum
。 因此,您必须添加logNum
作为依赖项,以便在num
和logNum
发生变化时更新效果:
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.