React实现简单递增定时器触发无限循环问题如何解决
问题原因分析
- useEffect依赖
countdown,每次countdown更新都会重新触发effect执行,生成新的定时器。原代码仅在countdown >= 10时才返回定时器清理函数,导致前9次触发effect生成的定时器没有被及时清除,多个定时器同时运行触发重复更新,最终陷入无限循环。 - 状态更新直接使用闭包内的
countdown值,属于依赖固定的写法,灵活性较差。
修复方案
方案1:保留依赖写法
调整清理逻辑的位置,确保每次effect重新执行前都会清理上一次生成的定时器,同时到阈值后不再生成新定时器:
import React, { useState, useEffect } from "react"; const Countdown = () => { const [countdown, setCountdown] = useState(0); useEffect(() => { // 计数到10后不再创建新定时器 if (countdown >= 10) return; const interval = setInterval(() => { // 使用函数式更新获取最新的状态值 setCountdown(prev => prev + 1); }, 1000); // 每次effect执行前/组件卸载时自动清理当前定时器 return () => clearInterval(interval); }, [countdown]); return <div>{countdown}</div>; }; export default Countdown;
方案2:无依赖更优写法
仅在组件挂载时创建一次定时器,在状态更新回调内判断阈值并清理,性能更高逻辑更简洁:
import React, { useState, useEffect } from "react"; const Countdown = () => { const [countdown, setCountdown] = useState(0); useEffect(() => { const interval = setInterval(() => { setCountdown(prev => { if (prev >= 10) { clearInterval(interval); return prev; } return prev + 1; }); }, 1000); // 组件卸载时兜底清理定时器 return () => clearInterval(interval); }, []); return <div>{countdown}</div>; }; export default Countdown;
内容的提问来源于stack exchange,提问作者Ryan Rigley
相关产品推荐
相关产品推荐

