React中clearInterval无法停止setInterval,intervalId为undefined问题
问题根源
React函数组件每次通过setCounter更新状态时,都会重新执行整个组件函数。你用let intervalId声明的是每次渲染的局部变量,每次组件重新渲染,这个变量都会被重新初始化回undefined。
当你点击start按钮调用runInterval,此时intervalId被赋值为定时器ID,但addToCounter里的setCounter会触发组件重新渲染,新的渲染上下文里intervalId又变成了undefined。这时候点击stop按钮,stopInterval拿到的是新渲染里的undefined,自然没法停止定时器。
而换成setInterval(()=>console.log(intervalId), 1000)时,定时器回调里没有更新组件状态,组件不会重新渲染,intervalId始终是第一次渲染时的那个变量,所以stopInterval能拿到正确的ID,功能就正常了。
修复方案
用React的useRef来保存定时器ID,useRef创建的引用在组件整个生命周期内都不会改变,不会随组件重新渲染而重置。
修改后的完整代码:
import { useState, useRef, useEffect } from 'react'; function Component() { const [counter, setCounter] = useState(0); // 用useRef存储定时器ID const intervalIdRef = useRef(null); function addToCounter() { setCounter((c) => c + 1); } function runInterval() { // 赋值给ref的current属性 intervalIdRef.current = setInterval(addToCounter, 1000); console.log(intervalIdRef.current); } function stopInterval() { // 通过current获取定时器ID并停止 clearInterval(intervalIdRef.current); // 清理引用,防止后续误操作 intervalIdRef.current = null; console.log(intervalIdRef.current); } // 组件卸载时自动清理定时器,避免内存泄漏 useEffect(() => { return () => { clearInterval(intervalIdRef.current); }; }, []); return ( <> <p>Value :{counter}</p> <button onClick={runInterval}>start interval</button> <button onClick={stopInterval}>stop interval</button> </> ); } export default Component;
内容的提问来源于stack exchange,提问作者Bogota
相关产品推荐
相关产品推荐

