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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.21 14:45:03