我正在使用Hooks构建REACT App,现在在使用useMemo()
和某些事件侦听器时遇到问题。我已经在CodeSandBox上准备了一个关于我的问题的更简单的演示:这是链接→https://codesandbox.io/s/mystifying-hertz-21jov?fontsize=14&hidenavigation=1&theme=dark。
现在,让我解释问题出在哪里:我有使用buttonData
计算的useMemo()
。现在,让我们看一下控制台输出:
首先,在第一次渲染时计算buttonData
,并且buttonData.behavior
等于test1
。然后,当我输入按钮时,在onMouseEnterButton
内部使用setTargetDOM
:这将触发重新计算buttonData
,因为setTargetDOM
是其依赖项之一。
到目前为止,一切都很好:
在控制台的第一行,我们看到buttonData.behavior
是test1
;
在第二行中,我们看到输入onMouseEnterButton
,现在buttonData.behavior
是test1
;
在第三行中,我们看到,由于targetDOM
已更改,因此我们再次计算了buttonData
,现在buttonData.beavhior
等于test2
;
现在,问题来了,我不明白的是!我可以以某种方式接受这样一个事实,即第四个控制台行告诉我buttonDat.behavior
仍然是test1
,因为我们仍处于更改targetDOM
并因此触发buttonData
进行更改的同一函数中(即使我期望甚至在第四行中也可以看到buttonData.behavior: test2
。
更糟糕的是,在onMouseMoveButton
内部,我看到buttonData.behavior
等于test1
,而不是test2
。
问题很简单。为什么?我的意思是,我认为我可以这样实现test2
,但是我想我这里缺少一些React Hook东西。
最佳答案
onMouseMoveButton
和onMouseEnterButton
在第一个渲染上捕获buttonData.behavior
,并且因为您从不更新事件侦听器,所以它们将始终引用buttonData.behavior
的初始值
您可以做的是将buttonData.behavior
添加到useLayoutEffect
的依赖项数组中,每次buttonData.behavior
更改时,它将运行返回的函数并删除先前的侦听器并添加新的侦听器
React.useLayoutEffect(() => {
...
}, [buttonData.behavior])
另外,状态更新是异步的,因此在第4行中,设置状态后您就不能真正地
log
更新状态setTargetDOM(e.currentTarget);
// this will never the updated value because
// the state updater hasn't run yet
console.log(buttonData.behavior);