You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 12:36:25