繁体   English   中英

来自在React.js UseEffect挂钩中创建的事件处理程序的访问状态

[英]Access state from Event Handler created within React.js UseEffect Hook

在我的组件中,我要在useEffect挂钩中设置一个事件侦听器:

useEffect(() => {
  const target = subtitleEl.current;
  target.addEventListener("click", () => {
    console.log("click");
    onSubtitleClick();
  });

  return () => {
    target.removeEventListener("click", null);
  };
}, []);

..但是当我调用onSubtitleClick ,我的状态是陈旧的-这是原始值。 示例代码在这里 如何从使用useEffect设置的事件处理程序中访问状态?

您的事件侦听器在定义的环境中注册了一个count为0的函数(引用),并且当发生新的渲染时,您的引用没有更新,该引用已注册到该元素,并且该注册的函数引用仍然知道计数为0即使计数已更改,但未注册更新的函数,该函数在其上下文中知道更新的值。 因此,您需要使用新的函数引用来更新事件侦听器。

useEffect(() => {
    const target = subtitleEl.current;
    target.addEventListener("click", onSubtitleClick);

    return () => {
      console.log("removeEventListener");
      target.removeEventListener("click", onSubtitleClick);
    };
}, [onSubtitleClick]);

但是,您不需要那些凌乱的代码即可实现您现在正在做的事情或类似的工作。 您可以在单击时简单地调用该传递的函数,而不必通过ref而是直接在jsx中附加到元素。

<div
    className="panelText"
    style={{ fontSize: "13px" }}
    onClick={onSubtitleClick}
    ref={subtitleEl}
  >
    Button2
</div>

我认为基本的addEventListener创建了自己的版本的封闭count独立于父组件的。 一个简单的解决方法是允许useEffect函数在更改时重新运行(删除[] arg):

useEffect(() => {
  const target = subtitleEl.current;
  target.addEventListener("click", () => {
    console.log("click");
    onSubtitleClick();
  });

  return () => {
    target.removeEventListener("click", null);
  };
}); // removed [] arg which prevents useeffect being run twice

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM