React开发秒表组件秒数按偶数递增跳数问题求助
问题根因
秒数按偶数递增是React 18 严格模式开发环境的副作用双重校验机制+缺少定时器清理逻辑共同导致的,和设置的1秒计时间隔无关:
- 现有代码中
useEffect传入空依赖数组,仅在组件挂载时执行,且没有返回副作用清理函数。 - React 18 开发环境开启严格模式时,会在组件首次挂载后主动触发一次「卸载-重新挂载」流程,用来提前暴露未正确清理的副作用问题。这个流程会让
setInterval被执行两次,生成两个间隔1秒、触发逻辑完全一致的定时器。 - 两个定时器的创建时间差极短,触发Tick的时机几乎重合:第一个定时器执行时把秒数ref+1更新为1触发重渲染,第二个定时器紧接着执行再把秒数+1更新为2触发重渲染,人眼无法捕捉到中间1、3、5这类奇数的显示状态,最终视觉上就呈现0-2-4-6的偶数递增效果。
修复方案
核心是给副作用加上定时器清理逻辑,避免重复创建定时器实例:
useEffect(()=>{ watch.current = setInterval(()=>{ if (!ispausedRef.current){ return; } Tick(); },1000) // 新增副作用清理:组件卸载/重挂载前清除已有定时器 return () => { clearInterval(watch.current) } },[])
其他需要注意的代码问题
- 初始状态对齐:默认
ispaused状态为false,对应ispausedRef初始值也是false,组件挂载初期定时器不会执行计时,如果需要默认启动秒表,记得把ref和状态的初始值统一设为true。 - JSX闭合:现有返回的DOM结构缺少最外层
</div>闭合标签,且initTicker/stopTicker/resethndler三个控制函数没有绑定到对应按钮的点击事件上,需要补充对应交互入口。 - 拼写误差:进度百分比的变量名
percantage为拼写错误,正确拼写为percentage,不影响运行但会提升后续维护的理解成本。
内容的提问来源于stack exchange,提问作者Arnab Ghosh
相关产品推荐
相关产品推荐

