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

React中正确使用setInterval的方法及React18下计数每次加2的原因

React中setInterval的正确用法与React 18计数翻倍问题解析

一、如何在React中正确使用setInterval?

React的渲染机制和闭包特性,要求使用setInterval时注意以下几点:

  • 必须配合清理函数:组件卸载或副作用重新执行时,一定要清除定时器,避免内存泄漏和无效定时器持续运行。
    基础示例:
    import { useState, useEffect } from 'react';
    
    function Timer() {
      const [count, setCount] = useState(0);
    
      useEffect(() => {
        const intervalId = setInterval(() => {
          // 用函数式更新获取最新状态,避开闭包陷阱
          setCount(prevCount => prevCount + 1);
        }, 1000);
    
        // 组件卸载时清除定时器
        return () => clearInterval(intervalId);
      }, []);
    
      return <div>当前计数:{count}</div>;
    }
    
  • 优先使用函数式更新状态:如果定时器回调里要更新状态,别直接用setCount(count + 1),这种写法会捕获渲染时的旧count值,导致状态更新滞后。用setCount(prev => prev + 1)能确保每次拿到最新的状态值。
  • 处理动态依赖:如果定时器的逻辑依赖props或其他state,一定要把这些依赖项加入useEffect的依赖数组。比如动态调整间隔时间:
    useEffect(() => {
      const intervalId = setInterval(() => {
        setCount(prev => prev + 1);
      }, updateInterval);
    
      return () => clearInterval(intervalId);
    }, [updateInterval]); // 依赖变化时重新创建定时器
    

二、React 18中count每次增加2的原因

这是React 18开发环境下Strict Mode的特性导致的:Strict Mode会自动执行两次组件挂载逻辑(包括useEffect的回调),用来检测未清理的副作用、重复挂载的bug等。

你提供的代码里,useEffect的空依赖数组会让它在组件挂载时执行,但因为没有清理函数,第一次执行创建的定时器没被清除,第二次执行又创建了一个新的定时器。两个定时器每秒都会调用setCount(prev => prev +1),所以count每秒会增加2。

修复方法

给useEffect加上清理函数,每次重新执行useEffect(包括Strict Mode的二次挂载)时,先清除旧定时器:

const [count, setCount] = useState(0)
useEffect(() => {
  const intervalId = setInterval(() => {
    setCount(count => count + 1)
  }, 1000)
  // 清理函数:在组件卸载或useEffect重新执行前清除定时器
  return () => clearInterval(intervalId)
}, [])

return (
  <div>{count}</div>
)

加上清理函数后,Strict Mode第二次执行useEffect时,会先清除第一次创建的定时器,最终只会保留一个正常工作的定时器,count就会每秒增加1了。另外要注意,这个问题只在开发环境出现,生产环境下Strict Mode不会触发二次挂载,但加上清理函数是必须的编码规范,能避免内存泄漏。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 11:56:19