在我的组件中,我在useEffect
钩子中设置了一个事件监听器:
useEffect(() => {
const target = subtitleEl.current;
target.addEventListener("click", () => {
console.log("click");
onSubtitleClick();
});
return () => {
target.removeEventListener("click", null);
};
}, []);
..但是当我打电话给onSubtitleClick
时,我的状态是陈旧的 - 这是原始值。 Example code here。如何从使用useEffect设置的事件处理程序中访问状态?
您的事件侦听器注册了一个函数(引用),它在定义的环境中将count
设置为0,并且当新的渲染发生时,您的引用未被更新,该引用在该元素中注册,并且注册的函数引用仍然知道count为0即使count已被更改,但更新的函数未注册,它知道其上下文中的更新值。因此,您需要使用新的函数引用更新事件侦听器。
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