我正在使用Hooks构建REACT应用程序,现在在使用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东西。
答案 0 :(得分:1)
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);