React.useMemo()和事件监听器

时间:2019-12-24 08:51:48

标签: javascript reactjs react-hooks

我正在使用Hooks构建REACT应用程序,现在在使用useMemo()和某些事件侦听器时遇到了问题。我已经在CodeSandBox上准备了我的问题的更简单演示:这是链接→https://codesandbox.io/s/mystifying-hertz-21jov?fontsize=14&hidenavigation=1&theme=dark

现在,让我解释问题出在哪里:我有buttonData,它是用useMemo()计算的。现在,让我们看一下控制台输出: enter image description here

首先,在第一次渲染时计算buttonData,并且buttonData.behavior等于test1。然后,当我输入按钮时,在onMouseEnterButton内使用setTargetDOM:这将触发buttonData的重新计算,因为setTargetDOM是其依赖项之一。
到目前为止,一切都很好:

  1. 在控制台的第一行中,我们看到buttonData.behaviortest1;
  2. 在第二行中,我们看到输入onMouseEnterButton,现在buttonData.behaviortest1;
  3. 在第三行我们看到,由于targetDOM已更改,因此我们再次计算了buttonData,现在buttonData.beavhior等于test2;

现在,问题来了,我不明白的是!我可以以某种方式接受以下事实:控制台的第四行告诉我buttonDat.behavior仍为test1,因为我们仍处于更改targetDOM并因此触发buttonData的相同功能中进行更改(即使我期望在第四行看到buttonData.behavior: test2

更糟糕的是,在onMouseMoveButton里面我看到buttonData.behavior等于test1,而不是test2

问题很简单。为什么?我的意思是,我认为我可以这样实现test2,但是我想我这里缺少一些React Hook东西。

1 个答案:

答案 0 :(得分:1)

onMouseMoveButtononMouseEnterButton在第一个渲染器上捕获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);