React函数组件setInterval失效,Timer组件停止重置按钮异常如何修复
Timer组件问题排查与修复方案
问题根源
所有功能异常的核心原因是useRef使用错误,导致定时器ID没有被正确存储,后续Stop、Reset操作无法清除正在运行的定时器,定时器持续执行setWatchData逻辑,覆盖了手动修改状态的结果。
具体错误点
- 启动定时器时直接覆盖了ref对象本身,而非将定时器ID存储到
timer.current属性,导致后续无法正确获取运行中的定时器ID - 组件销毁的useEffect清理函数中,错误将ref对象本身传入
clearInterval,而非timer.current存储的ID setInterval未指定执行间隔,会以浏览器最小允许间隔高频执行,产生不必要的性能开销handleLap方法中直接取闭包中的watchData.timestamps拼接,存在闭包旧值风险
修复后完整代码
import React, { useEffect, useState, useRef } from "react"; const initialState = { status: false, runningTime: 0, timestamps: [] }; export const Timer = () => { const [watchData, setWatchData] = useState(initialState); const timer = useRef(null); useEffect(() => { return () => { clearInterval(timer.current); }; }, []); const getUnits = (time) => { const seconds = time / 1000; const min = Math.floor(seconds / 60).toString(); const sec = Math.floor(seconds % 60).toString(); const msec = (seconds % 1).toFixed(3).substring(2); return `${min.padStart(2, '0')}:${sec.padStart(2, '0')}:${msec}`; }; const handleClick = () => { const { status } = watchData; if (!status) { const startTime = Date.now() - watchData.runningTime; timer.current = setInterval(() => { setWatchData((prevState) => ({ ...prevState, status: true, runningTime: Date.now() - startTime })); }, 10); } else { clearInterval(timer.current); setWatchData((prevState) => ({ ...prevState, status: false })); } }; const handleReset = () => { clearInterval(timer.current); setWatchData({ ...initialState }); }; const handleLap = () => { const timestamp = getUnits(watchData.runningTime); setWatchData((prevState) => ({ ...prevState, timestamps: [...prevState.timestamps, timestamp] })); }; return ( <> <p>{getUnits(watchData.runningTime)}</p> <button onClick={handleClick}> {watchData.status ? "Stop" : "Start"} </button> <button onClick={handleReset}>Reset</button> <button onClick={handleLap}>Lap</button> {watchData.timestamps.length > 0 && ( <ul> {watchData.timestamps.map((t, index) => ( <li key={index}>{t}</li> ))} </ul> )} </> ); };
内容的提问来源于stack exchange,提问作者Mrs.Smith
相关产品推荐
相关产品推荐

