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

React函数组件setInterval无法获取更新props的更优方案咨询

问题解答:React函数组件setInterval中无法获取更新后的props值

问题根源

这是典型的闭包陷阱:Component1中的useEffect依赖数组为空,意味着它仅在组件挂载时执行一次。setInterval的回调函数捕获了挂载时的counter闭包,后续组件因counter更新重新渲染时,这个闭包不会同步更新,所以console.log始终输出初始值。

解决方案

方案1:将props加入useEffect依赖列表(更简洁)

直接把counter添加到useEffect的依赖数组中,每次counter更新时,自动清除旧的定时器并创建新的,新的回调会捕获最新的counter值:

const Component1 = ({ counter }) => {
  useEffect(() => {
    const intervalID = setInterval(() => {
      console.log(counter);
    }, 1000);

    return () => {
      clearInterval(intervalID);
    };
  }, [counter]); // 加入counter作为依赖

  return <h1>Component1 count: {counter}</h1>;
};

这种方案无需额外创建ref,代码逻辑更直观,对于每秒更新的场景,定时器销毁重建的性能开销可以完全忽略。

方案2:使用useRef(无频繁定时器重建)

如果需要让定时器持续运行不中断,同时获取最新的props,你的原方案是可行的。不用担心ref的内存开销——单个ref占用的内存极小,完全不会影响性能。可以保持原写法,或者稍作优化(将ref赋值逻辑放到useEffect中,避免每次渲染都执行,但实际差异可忽略):

const Component1 = ({ counter }) => {
  const counterRef = useRef(counter);

  // 仅在counter更新时同步ref
  useEffect(() => {
    counterRef.current = counter;
  }, [counter]);

  useEffect(() => {
    const intervalID = setInterval(() => {
      console.log(counterRef.current);
    }, 1000);

    return () => {
      clearInterval(intervalID);
    };
  }, []);

  return <h1>Component1 count: {counter}</h1>;
};

方案选择

  • 若定时器逻辑需要随props更新调整(比如不同counter值对应不同的定时行为),优先选方案1;
  • 若需要定时器持续运行不中断,同时获取最新props,选方案2。

两种方案都是React中的正确实践,没有绝对的“最优”,需根据实际场景选择。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.31 17:45:28