React定时器函数无法实时响应props.performanceData更新的问题
React定时器未响应props更新的问题分析与解决
问题根源
- 闭包陷阱:定时器回调在组件首次渲染时创建,会捕获当时的
performanceData和numberCount值。后续props更新触发组件重渲染,但旧定时器回调依然引用初始渲染时的变量,无法获取最新props。 - 未监听props变化:组件更新时没有重新配置定时器,导致回调始终使用旧的
performanceData。
解决方法
方法1:用useRef保存最新值
通过useRef实时同步performanceData和状态的最新值,让定时器回调能拿到实时数据:
import { useState, useEffect, useRef } from 'react'; function RecordingComponent({ performanceData }) { const [numberCount, setNumberCount] = useState(0); const performanceRef = useRef(performanceData); const countRef = useRef(numberCount); // 每次props或状态更新时,同步ref的值 useEffect(() => { performanceRef.current = performanceData; countRef.current = numberCount; }, [performanceData, numberCount]); useEffect(() => { const timer = setInterval(() => { if (performanceRef.current >= 70) { setNumberCount(prev => prev + 1); countRef.current += 1; } }, 1000); return () => clearInterval(timer); }, []); return <div>计数:{numberCount}</div>; }
方法2:让定时器依赖performanceData
把performanceData加入定时器的依赖数组,每次props变化时清除旧定时器并创建新的,确保回调使用最新值:
import { useState, useEffect } from 'react'; function RecordingComponent({ performanceData }) { const [numberCount, setNumberCount] = useState(0); useEffect(() => { const timer = setInterval(() => { if (performanceData >= 70) { setNumberCount(prev => prev + 1); } }, 1000); // 组件卸载或props变化时清除定时器 return () => clearInterval(timer); }, [performanceData]); return <div>计数:{numberCount}</div>; }
方法3:函数式更新状态(配合props依赖)
如果只需要保证状态更新基于最新值,用setNumberCount的函数式更新,同时把performanceData加入依赖:
import { useState, useEffect } from 'react'; function RecordingComponent({ performanceData }) { const [numberCount, setNumberCount] = useState(0); useEffect(() => { const timer = setInterval(() => { if (performanceData >= 70) { // 函数式更新自动获取最新的状态值 setNumberCount(prev => prev + 1); } }, 1000); return () => clearInterval(timer); }, [performanceData]); return <div>计数:{numberCount}</div>; }
方法说明
- 方法1适合需要在定时器中访问多个实时变量的场景,ref会持续同步最新值,无需频繁重启定时器。
- 方法2逻辑简单直接,但如果
performanceData频繁变化,会导致定时器频繁销毁重建,需根据业务场景评估。 - 方法3是状态更新的优化方式,确保状态更新基于最新值,但必须配合props依赖才能让回调感知到
performanceData的变化。
内容的提问来源于stack exchange,提问作者Gustav
相关产品推荐
相关产品推荐

