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

React中通过loading状态清除setInterval计时器失效问题

问题根源

代码不生效是典型的React闭包陷阱:
setInterval的回调在创建时就捕获了当前作用域下的loading值(也就是调用getPrestoData刚执行完setLoading(true)时的true值),后续setLoading(false)触发组件重渲染,根本不会更新这个已经存在的定时器回调里的loading变量,所以if (!loading)的判断永远不会成立,定时器自然不会自动停止。
另外当前写法还有隐患:请求走catch分支时既没有把loading设回false,也没有清除定时器,会进一步导致状态异常。

修复方案

不要在定时器内部依赖state判断停止时机,直接在请求流程结束(无论成功/失败)时手动清除定时器即可,这是最可靠的实现方式:

const [loading, setLoading] = useState(null)
const [error, setError] = useState('')
// Counter
const [count, setCounter] = useState(0)

const getPrestoData = async () => {
  setLoading(true)
  setCounter(0) // 每次发起新请求前重置计数
  let currentCount = 0

  // 保存定时器ID
  const timer = setInterval(() => {
    currentCount++
    setCounter(currentCount)
  }, 1000)

  try {
    const response = await fetch(`http://127.0.0.1:8000/get-dspdaily/${dealId}`)
    const data = await response.json()
    setData(data)
    setDealId('')
  } catch (err) {
    console.log(err)
    setError(err)
  } finally {
    // 无论请求成功还是失败,都停止计数、关闭loading状态
    clearInterval(timer)
    setLoading(false)
  }
}
可选优化

如果组件可能在请求过程中被卸载,建议把定时器ID存在useRef中,在组件卸载时主动清除,避免内存泄漏:

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

// 组件内新增ref存定时器id
const timerRef = useRef(null)

const getPrestoData = async () => {
  setLoading(true)
  setCounter(0)
  let currentCount = 0

  timerRef.current = setInterval(() => {
    currentCount++
    setCounter(currentCount)
  }, 1000)

  try {
    const response = await fetch(`http://127.0.0.1:8000/get-dspdaily/${dealId}`)
    const data = await response.json()
    setData(data)
    setDealId('')
  } catch (err) {
    console.log(err)
    setError(err)
  } finally {
    clearInterval(timerRef.current)
    setLoading(false)
  }
}

// 组件卸载时兜底清定时器
useEffect(() => {
  return () => {
    if (timerRef.current) clearInterval(timerRef.current)
  }
}, [])

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 18:57:21