React计数器自动增减冲突求助:无法正确清除interval定时器
问题分析与解决方案
你的问题核心在于用普通变量存储intervalId,React组件每次重渲染时,这个变量会被重新初始化,导致stopInterval无法获取到当前有效的定时器ID,旧的定时器没有被清除,最终出现自动递增和递减同时执行的情况。
修复方案:使用useRef保存定时器ID
useRef的.current属性在组件整个生命周期中保持不变,不会随重渲染重置,能准确存储和获取最新的定时器ID。
修改后的完整代码示例
import { useState, useRef, useEffect } from 'react'; function Counter() { const [counter, setCounter] = useState(0); // 用useRef存储定时器ID const intervalIdRef = useRef(null); const stopInterval = () => { if (intervalIdRef.current) { clearInterval(intervalIdRef.current); intervalIdRef.current = null; } }; const handleAutoDecrement = () => { stopInterval(); intervalIdRef.current = setInterval(() => { setCounter((prev) => prev - 1); }, 1000); }; const handleAutoIncrement = () => { stopInterval(); intervalIdRef.current = setInterval(() => { setCounter((prev) => prev + 1); }, 1000); }; // 组件卸载时清除定时器,防止内存泄漏 useEffect(() => { return () => { stopInterval(); }; }, []); return ( <div> <p>计数:{counter}</p> <button onClick={handleAutoIncrement}>自动递增</button> <button onClick={handleAutoDecrement}>自动递减</button> <button onClick={stopInterval}>停止</button> </div> ); } export default Counter;
关键修改说明
useRef存储ID:替代普通变量,确保定时器ID在组件重渲染后依然有效,stopInterval能准确清除当前运行的定时器。- 完善
stopInterval逻辑:先判断intervalIdRef.current是否存在,避免无效的clearInterval调用。 - 组件卸载清理:通过
useEffect的返回函数,在组件卸载时自动清除定时器,防止内存泄漏问题。
内容的提问来源于stack exchange,提问作者Shreyas Agarwal
相关产品推荐
相关产品推荐

