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

React中如何在按钮每次状态变更时重置setTimeout计时器?

解决方案

要实现「每次按钮状态变更后都重置3秒倒计时」,核心是清除上一次未执行的定时器,避免多个定时器冲突。这里可以用useRef来保存定时器ID,它的值在组件生命周期内保持稳定,不会触发重渲染。

步骤说明

  1. 用useRef存储定时器ID:确保组件多次渲染后仍能访问到同一个定时器引用,不会因状态更新丢失。
  2. 每次触发前清除旧定时器:在useEffect中,先清除之前可能存在的未完成定时器,再设置新的倒计时,保证倒计时从当前状态开始重新计算3秒。
  3. 修复onClick的状态判断:原代码的连续if会因setState异步特性导致逻辑错误(比如第一次点击直接跳转到最后状态),改用函数式更新获取最新状态,确保判断准确。
  4. 组件卸载时清理定时器:防止组件卸载后定时器仍执行,造成不必要的状态更新或内存泄漏。

修改后的完整代码

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

const TestButton = () => {
    const initialText = "Click me!"
    const changedText = "You clicked me!"
    const lastText = "Stop clicking me!"
    const [buttonText, setButtonText] = useState(initialText)
    const timerRef = useRef(null); // 存储定时器ID

    const onClick = () => {
        // 函数式更新获取最新状态,避免异步判断错误
        setButtonText(prevText => {
            if (prevText === initialText) {
                return changedText;
            } else if (prevText === changedText) {
                return lastText;
            }
            return prevText; // 点击最后状态时保持不变,可按需调整
        });
    };

    useEffect(() => {
        // 清除上一次的定时器
        if (timerRef.current) {
            clearTimeout(timerRef.current);
        }

        if (buttonText !== initialText) {
            // 设置新定时器并保存ID
            timerRef.current = setTimeout(() => {
                setButtonText(initialText);
            }, 3000);
        }

        // 组件卸载时清理定时器
        return () => {
            if (timerRef.current) {
                clearTimeout(timerRef.current);
            }
        };
    }, [buttonText, initialText]);
    
    return (
        <button
            type="button"
            className={"btn btn-primary"}
            onClick={onClick}
        >
            {buttonText}
        </button>
    );
};

export default TestButton;

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 06:35:18