You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

useEffect未配置清理函数导致点击计数非预期递增的原因是什么?

问题原因分析

大量事件监听器的挂载逻辑

你写的useEffect没有传入第二个依赖数组参数,按照React的规则,这种写法下每次组件渲染完成后都会执行一次useEffect的回调函数:

  • 组件初次加载会触发第一次渲染,useEffect执行,新增第一个mousedown监听
  • 后续每次调用setClickCount更新状态都会触发组件重渲染,每重渲染一次,useEffect就会再执行一次,新增一个新的mousedown监听
  • 旧的监听没有做清理,会一直挂载在document对象上,监听器的数量会随着渲染次数线性增长。

对计数结果的影响逻辑

你用的是函数式更新写法setClickCount(prev => prev + 1),这种写法每次都会拿到当前最新的count值做更新,所以所有挂载的监听器触发的更新都会生效:

  • 初次渲染完成后,仅存在1个监听器,点击一次触发1次更新,count从0变成1,触发重渲染
  • 重渲染后新增1个监听器,此时总共2个监听器,点击一次触发2次更新,count从1变成1+2=3,再次触发重渲染
  • 若这次重渲染过程中因为其他逻辑多触发了一次渲染,就会累计到4个监听器,点击一次触发4次更新,count从3变成3+4=7,和你观察到的现象一致。
    本质上每次点击的增量等于当前已挂载的监听器总数量,所以count不会按预期每次加1,而是会越来越快地增长。

修复方案

只要给useEffect补充清理逻辑,同时指定空依赖数组,让监听只挂载一次即可:

useEffect(() => {
  document.addEventListener('mousedown', increment);
  // 清理函数,组件卸载时自动移除监听
  return () => document.removeEventListener('mousedown', increment);
}, []);

内容的提问来源于stack exchange,提问作者Hussam

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.28 08:06:02