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

React中useEffect与setInterval异常行为及清理函数作用解析

React StrictMode下useEffect与setInterval的异常分析与解决方案

问题场景

在React应用中使用useEffect结合setInterval时出现异常:

  • 不添加清理函数时,count每次递增2而非预期的1
  • 添加清理函数return () => { clearInterval(id); };后,count恢复正常每次递增1
  • 移除index.js中的<React.StrictMode>,即使没有清理函数也能正常运行

对应的代码片段:

import React, { useState, useEffect } from "react";

function Timer() {
  const [count, setCount] = useState(0);

  useEffect(() => {
    const id = setInterval(() => {
      setCount((prevCount) => prevCount + 1);
    }, 1000);
    // 取消注释下方清理函数后,功能正常
    // return () => {
    //   clearInterval(id);
    // };
  }, []);

  return (
    <div className="Timer">
      <h2>Timer Two</h2>
      <h3>{count}</h3>
    </div>
  );
}

export default Timer;

原因解析

<React.StrictMode>的作用

StrictMode是React仅在开发环境生效的工具,核心目的是提前揪出代码里潜在的副作用问题。它会刻意重复执行以下操作:

  • 组件构造函数、useState初始化函数、useReducer更新函数
  • useEffect和useLayoutEffect的回调函数及其清理函数

这种重复执行是为了暴露那些没正确处理清理逻辑的副作用,比如未销毁的定时器、订阅等,避免上线后出现内存泄漏或异常行为。

无清理函数时的异常原因

当没有清理函数时,StrictMode的双重执行会导致:

  1. 第一次执行useEffect,创建定时器A,每1秒触发一次setCount
  2. StrictMode触发第二次useEffect执行,又创建定时器B,同样每1秒触发一次setCount
  3. 两个定时器并行运行,每1秒各自调用一次setCount,所以count每次会被加2

清理函数解决问题的原理

添加return () => { clearInterval(id); };后,StrictMode的执行流程变成了:

  1. 第一次执行useEffect,创建定时器A
  2. StrictMode准备第二次执行useEffect前,会先调用第一次useEffect返回的清理函数,清除定时器A
  3. 第二次执行useEffect,创建定时器B
  4. 此时页面上只有定时器B在运行,每1秒触发一次setCount,count自然每次递增1

另外,清理函数还有个关键作用:当组件卸载时,会自动执行清理逻辑清除定时器,避免内存泄漏——这也是React副作用管理的最佳实践,不管有没有StrictMode都应该加上。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.10 05:36:17