React中onMouseUp触发clearInterval无法清除setInterval的问题
问题:React按钮按住启动定时器,松开后无法停止
我尝试实现按钮的onMouseDown事件,按住时启动定时器每隔1秒执行指定函数,松开按钮(onMouseUp)时清除定时器,但释放按钮后定时器仍持续运行。
当前代码:
import React from "react"; function PlantDefuser() { var interval function planting() { interval = setInterval(() => { console.log("Defuser Planted") }, 1000) } function notPlanting() { console.log(interval) clearInterval(interval) } return ( <button onMouseDown={planting} onMouseUp={notPlanting}>Press and Hold</button> ) } export default PlantDefuser
解决方案
问题根源是:函数组件每次渲染时,内部声明的var interval会被重新初始化,导致notPlanting中访问的interval可能不是planting中赋值的那个定时器引用,自然无法清除。
修复步骤:使用useRef保存定时器引用
React的useRef可以在组件多次渲染之间持久化保存同一个值,不会随渲染重置。修改后的代码如下:
import React, { useRef, useEffect } from "react"; function PlantDefuser() { const intervalRef = useRef(null); function planting() { // 先清除已存在的定时器,避免重复创建 if (intervalRef.current) { clearInterval(intervalRef.current); } intervalRef.current = setInterval(() => { console.log("Defuser Planted"); }, 1000); } function notPlanting() { if (intervalRef.current) { clearInterval(intervalRef.current); intervalRef.current = null; // 重置引用,避免无效值 } } // 组件卸载时自动清除定时器,防止内存泄漏 useEffect(() => { return notPlanting; }, []); return ( <button onMouseDown={planting} onMouseUp={notPlanting}>Press and Hold</button> ); } export default PlantDefuser;
核心改动说明:
- 用
useRef替代普通变量存储定时器ID,确保跨渲染周期引用一致 - 在
planting中先检查并清除旧定时器,避免多次触发onMouseDown创建多个定时器 notPlanting清除定时器后重置intervalRef.current,避免保留无效引用- 添加
useEffect清理函数,组件卸载时自动清除定时器,防止内存泄漏
内容的提问来源于stack exchange,提问作者SquidDOTjpeg
相关产品推荐
相关产品推荐

