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

React中setInterval与clearInterval引发状态重复问题求助

React基础倒计时器问题解决

问题描述

你需要实现一个初始30秒的React倒计时器,点击按钮可重置并重新开始倒计时。最初未更新状态时控制台输出正常,但启用setSeconds更新页面渲染后,出现console.log重复、渲染加倍、双重倒计时同时运行的异常。

原始代码

const [seconds, setSeconds] = useState(30)
let interval = null

function startTimer() {
    stopTimer()
    let start = 30
    interval = setInterval(() => {
        // setSeconds(start)
        console.log('start: ', start)
        start--
    }, 1000)
}

function stopTimer() {
    clearInterval(interval)
}

return (
    <p>{seconds}s</p>
    <button onClick={startTimer}>Start</button>
)

问题根源

  • 组件内部声明的interval变量会随每次渲染重新初始化,无法有效追踪定时器实例
  • React开发环境的StrictMode会触发两次渲染,导致多个定时器实例同时运行,进而引发重复日志和状态异常更新

解决方案

使用useRef保存定时器引用(其值在组件生命周期内保持稳定),结合函数式状态更新确保状态同步:

import { useState, useRef, useEffect } from 'react';

function CountdownTimer() {
    const [seconds, setSeconds] = useState(30);
    const intervalRef = useRef(null);

    function startTimer() {
        // 清除已有定时器
        if (intervalRef.current) {
            clearInterval(intervalRef.current);
        }
        // 重置秒数
        setSeconds(30);
        // 启动新定时器
        intervalRef.current = setInterval(() => {
            setSeconds(prevSeconds => {
                if (prevSeconds <= 1) {
                    clearInterval(intervalRef.current);
                    return 0;
                }
                return prevSeconds - 1;
            });
        }, 1000);
    }

    // 组件卸载时清理定时器,避免内存泄漏
    useEffect(() => {
        return () => {
            intervalRef.current && clearInterval(intervalRef.current);
        };
    }, []);

    return (
        <div>
            <p>{seconds}s</p>
            <button onClick={startTimer}>Start/Reset</button>
        </div>
    );
}

export default CountdownTimer;

关键改动说明

  • useRef存储定时器引用:确保跨渲染周期保持同一引用,避免丢失对定时器的追踪
  • 函数式状态更新:setSeconds(prevSeconds => ...)保证每次获取最新的状态值,避免闭包导致的状态滞后
  • 卸载清理:通过useEffect的清理函数在组件卸载时清除定时器,防止内存泄漏
  • 自动终止逻辑:倒计时至0时主动清除定时器,避免无效的定时器运行

内容的提问来源于stack exchange,提问作者Eric Winkelspecht

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 04:10:30