React中setInterval每秒更新时间后无法成功清除定时器问题
问题根源
- 你的
useEffect依赖项设置了MyTime,每次setMyTime更新状态后都会触发useEffect重新执行,旧定时器还没清除就会新增一个定时器,timerClear每秒都会被赋值为新的定时器ID,所以你打印的时候每次值都不一样,清除时也只能清掉最新的一个,之前的定时器会一直后台运行。 - 你用普通
var声明timerClear,函数组件每次重渲染都会生成新的作用域,这个变量的值跨渲染无法保持同步,很容易拿到过期的ID。
修复方案
第一步:用useRef存储定时器ID
useRef的current属性在组件整个生命周期内是同一个引用,可以稳定存储定时器ID,不会因为组件重渲染丢失值。
第二步:给useEffect添加清理逻辑
每次useEffect重新执行或者组件卸载前,先清除上一轮的定时器,避免堆积多个定时器。
第三步:调整useEffect依赖项
你要实现每秒更新时间的逻辑,不需要依赖MyTime,依赖项留空只在组件挂载时初始化一次定时器即可,避免死循环。
修正后代码
定时器初始化部分
import { useState, useEffect, useRef } from 'react'; // 用useRef存定时器ID const timerClearRef = useRef(null); const [MyTime, setMyTime] = useState(''); useEffect(() => { // 开新定时器前先清旧的 if (timerClearRef.current) { clearInterval(timerClearRef.current); } timerClearRef.current = setInterval(() => { // 每次回调取最新的当前时间 const realeTime = new Date(); setMyTime( realeTime.toLocaleTimeString([], { timeZone: "Asia/Tehran", hour: '2-digit', minute: '2-digit', second: '2-digit', hour12: false, }), ); checkTime(); }, 1000); // 清理函数:组件卸载/useEffect重跑前清定时器 return () => { clearInterval(timerClearRef.current); }; // 依赖项留空,仅挂载时执行一次 }, []);
清除定时器部分
if (filterGetTime > filterEndTime) { if (data.examParents[0].examParent_method == "0") { console.log('timerClear', timerClearRef.current); alert('زمان امتحان تمام شده است!!!'); if(sendReqDelay){ clearTimeout(sendReqDelay); } clearTimeout(setTimeToPageTimeOut); clearTimeout(TimerIntervalSolveQuestions); // 清除ref中存储的定时器 clearInterval(timerClearRef.current); timerClearRef.current = null; } }
内容的提问来源于stack exchange,提问作者zahraei
相关产品推荐
相关产品推荐

