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

React Hooks:如何让函数在每次事件触发时执行(不受状态变化影响)

问题分析与解决方案

问题代码

var [testVar, setTestVar] = useState(0)

var showTestVar = () => {
  console.log(testVar)
}

var effectTest = () => {
  setTestVar(1)
  setInterval(showTestVar, 1000)
}

需求

让showTestVar每次被setInterval触发时,都能执行并获取到最新的testVar状态值,无论状态是否变化。

当前问题原因

showTestVar是组件渲染时创建的函数,它通过闭包捕获了当前渲染周期的testVar值。当setTestVar(1)触发组件重新渲染后,会生成一个新的showTestVar函数(捕获了testVar=1),但之前的定时器仍在调用旧的showTestVar(捕获了testVar=0),导致日志同时出现新旧状态值。


解决方案

方案1:使用useRef保存最新状态引用

useRef的.current属性是可变的,不会触发组件渲染,我们可以用它同步最新的状态值,让showTestVar每次调用都能拿到最新值:

import { useState, useRef, useEffect } from 'react';

function TestComponent() {
  const [testVar, setTestVar] = useState(0);
  // 用ref保存最新的testVar值
  const testVarRef = useRef(testVar);
  // 状态更新时同步ref
  useEffect(() => {
    testVarRef.current = testVar;
  }, [testVar]);

  const showTestVar = () => {
    // 访问ref的current属性获取最新值
    console.log(testVarRef.current);
  };

  // 用ref保存定时器ID,方便清理
  const intervalRef = useRef(null);

  const effectTest = () => {
    // 先清除已有定时器,避免重复创建
    if (intervalRef.current) {
      clearInterval(intervalRef.current);
    }
    setTestVar(1);
    intervalRef.current = setInterval(showTestVar, 1000);
  };

  // 组件卸载时清理定时器,防止内存泄漏
  useEffect(() => {
    return () => {
      if (intervalRef.current) {
        clearInterval(intervalRef.current);
      }
    };
  }, []);

  return <button onClick={effectTest}>触发测试</button>;
}

方案2:直接在定时器回调中读取最新状态(简化版)

如果不需要复用showTestVar函数,可以直接在定时器回调里通过函数式更新获取最新状态:

const effectTest = () => {
  setTestVar(1);
  // 用函数式更新读取最新状态,不修改状态
  setInterval(() => {
    setTestVar(prev => {
      console.log(prev);
      return prev; // 仅读取,不更新状态
    });
  }, 1000);
};

关键注意点

  • 务必清理定时器:每次创建新定时器前清除旧的,组件卸载时也需清除,避免内存泄漏和多个定时器同时运行。
  • useRef是处理闭包捕获旧值问题的通用方案,适用于需要在异步回调中获取最新状态/属性的场景。

内容的提问来源于stack exchange,提问作者Gene Knight

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 08:40:18