React方法组件添加事件监听器产生的闭包问题如何解决?

作者站长头像
站长
· 阅读数 9

示例代码如下,通过DOM2的addEventListener方式添加的事件监听器,总读取不到最新的count值。但如果我采用React的合成事件onClick以及将count移出到TestDemo外,可以解决该问题,但我不明白此处为何会产生闭包

const TestDemo = (props: any) => {
  const [count, setCount] = useState(0);

  useEffect(() => {
    const btn = document.getElementById('btn');
    if (btn) {
      btn.addEventListener('click', handleClick);
    }
  }, []);

  const handleClick = () => {
    console.log(count);
    setCount(count + 1);
  };

  return (
    <div>
      <button id={'btn'}>点击</button>
    </div>
  );
};
回复
1个回答
avatar
test
2024-07-13

如评论区大佬所言,React Hooks 闭包陷阱的文章俯拾皆是。这里主要是回调函数handleClick中捕获了 count,因此应当将 count 纳入依赖,除此之外副作用需要及时清除:

 useEffect(() => {
    const btn = document.getElementById('btn');
    if (btn) {
      btn.addEventListener('click', handleClick);
      return () =>{
        // 清除副作用
        btn.removeEventListener('click', handleClick);
      }
    }
  }, [count]);
回复
likes
适合作为回答的
  • 经过验证的有效解决办法
  • 自己的经验指引,对解决问题有帮助
  • 遵循 Markdown 语法排版,代码语义正确
不该作为回答的
  • 询问内容细节或回复楼层
  • 与题目无关的内容
  • “赞”“顶”“同问”“看手册”“解决了没”等毫无意义的内容