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

React实现长按按钮实时计时遇state更新无限循环问题求助

解决React长按按钮实时计数时的无限循环问题

你的问题核心在于组件重新渲染时普通变量会被重置,加上定时器创建逻辑的疏漏,导致每次调用setMs触发组件重渲染后,又会重新执行相关逻辑,最终引发无限循环。我来给你一步步修复:

问题分析

原代码里的counter和timerinterval是组件内的普通变量,每次组件因setMs更新状态而重新渲染时,这两个变量都会被重新初始化(let counter = 0; let timerinterval;)。同时setInterval的第二个参数你写成了数组[1000],这是错误的,而且timer函数里的条件判断逻辑也容易导致重复创建定时器,进一步加剧循环问题。

修复后的代码

import React, { useState, useEffect, useRef } from "react";

const Emergency = () => {
  const [ms, setMs] = useState(0);
  // 用useRef保存定时器和计数器,避免组件重渲染时被重置
  const timerRef = useRef(null);
  const counterRef = useRef(0);

  const startTimer = () => {
    // 先清除可能存在的旧定时器,防止重复创建
    if (timerRef.current) clearInterval(timerRef.current);
    
    counterRef.current = 1;
    setMs(counterRef.current);
    
    timerRef.current = setInterval(() => {
      counterRef.current += 1;
      setMs(counterRef.current);
    }, 1000);
  };

  const stopTimer = () => {
    if (timerRef.current) {
      clearInterval(timerRef.current);
      timerRef.current = null;
    }
    counterRef.current = 0;
    setMs(0);
  };

  const pressingDown = (e) => {
    e.preventDefault();
    startTimer();
  };

  const notPressingDown = (e) => {
    e.preventDefault();
    stopTimer();
  };

  // 组件卸载时清理定时器,防止内存泄漏
  useEffect(() => {
    return () => {
      if (timerRef.current) clearInterval(timerRef.current);
    };
  }, []);

  return (
    <>
      <button
        onMouseDown={pressingDown}
        onMouseUp={notPressingDown}
        onTouchStart={pressingDown}
        onTouchEnd={notPressingDown}
        className="button is-primary mt-3"
      >
        Emergency
      </button>
      <br />
      Time holding it is.... {ms}
    </>
  );
};

export default Emergency;

关键修改点

  • 用useRef存储定时器和计数器:useRef的.current属性在组件整个生命周期内保持不变,不会因组件重渲染而重置,完美解决了原代码中变量被重复初始化的问题。
  • 完善定时器创建/清理逻辑:每次启动定时器前先清除旧的,避免多个定时器同时运行;停止时彻底清空定时器引用,防止内存泄漏。
  • 修正setInterval参数:把错误的数组[1000]改成正确的毫秒数1000。
  • 添加组件卸载时的清理:通过useEffect的返回函数,在组件被卸载时自动清除定时器,避免潜在的内存泄漏问题。

这样修改后,长按按钮时会实时更新秒数,松开后重置为0,而且不会再出现无限循环的问题,完全满足你的用户体验需求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.08 11:07:45