React中如何在按钮每次状态变更时重置setTimeout计时器?
解决方案
要实现「每次按钮状态变更后都重置3秒倒计时」,核心是清除上一次未执行的定时器,避免多个定时器冲突。这里可以用useRef来保存定时器ID,它的值在组件生命周期内保持稳定,不会触发重渲染。
步骤说明
- 用useRef存储定时器ID:确保组件多次渲染后仍能访问到同一个定时器引用,不会因状态更新丢失。
- 每次触发前清除旧定时器:在
useEffect中,先清除之前可能存在的未完成定时器,再设置新的倒计时,保证倒计时从当前状态开始重新计算3秒。 - 修复onClick的状态判断:原代码的连续
if会因setState异步特性导致逻辑错误(比如第一次点击直接跳转到最后状态),改用函数式更新获取最新状态,确保判断准确。 - 组件卸载时清理定时器:防止组件卸载后定时器仍执行,造成不必要的状态更新或内存泄漏。
修改后的完整代码
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
相关产品推荐
相关产品推荐

