我的目标是在按下键盘按钮时执行操作,使用我用
useState
声明的变量的当前值。
我在下面的代码示例中重现了我的问题:
import React from 'react';
import { HotKeys } from 'react-hotkeys';
import { useCallback, useEffect, useMemo, useState } from 'react';
const keyMap = {
MOVE_DOWN: 'a'
};
export function App(props) {
const [test, setTest] = useState(0);
const focusNextRow = useCallback(() => {
console.log("test", test);
setTest(test => test + 1);
console.log("test2", test);
}, [test]);
useEffect(() => {
console.log("TEST IS NOW ", test);
}, [test]);
const handlers = {
MOVE_DOWN: focusNextRow
};
return (
<div className='App'>
<HotKeys keyMap={keyMap} handlers={handlers}>
<div>test</div>
</HotKeys>
</div>
);
}
结果如下所示:
如您所见:组件中的
test
值已更新,但按下键盘时调用的方法始终具有此状态的默认值(即0)。我该如何解决这个问题?
您的意外行为似乎来自于使用
useCallback
显然,它被称为这个问题中引用的Clusure Issue。
关闭问题您看到的行为与 JavaScript 有关 闭包以及 React 的钩子如何捕获值。当使用回调时 创建一个记忆回调,它捕获状态值 创建回调的时间。即使您将状态包含在 依赖数组,useEffect 中的清理函数与 在初始渲染期间创建的原始闭包。这 时间轴
初始渲染:状态为0,创建回调捕获
useEffect 运行:调用state = 0
组件重新渲染:状态现在为setState(1)
当组件卸载时:清理函数使用原始函数运行 回调1