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

如何基于SWR返回的响应数据触发重新拉取请求

正确实现方案

现有代码的问题

  • 直接在组件渲染逻辑中调用setTimeout,会导致每次组件重渲染时只要目标字段不存在就创建新的定时器,最终出现大量重复请求、内存泄漏的问题
  • 没有对定时器做清理逻辑,组件卸载后定时器仍然会触发请求

方案1:useEffect + 手动定时器控制

适合需要自定义复杂重试逻辑的场景,需要手动处理副作用清理:

import { useEffect, useRef } from 'react'

const { data, mutate } = useSWR(key, fetcher)
// 可选:添加最大重试次数限制,避免后端异常时无限轮询
const retryCountRef = useRef(0)
const MAX_RETRY = 10

useEffect(() => {
  // 目标字段存在时直接返回,重置重试计数
  if (typeof data?.someData !== "undefined") {
    retryCountRef.current = 0
    return
  }
  // 超过最大重试次数停止轮询
  if (retryCountRef.current >= MAX_RETRY) return

  const timer = setTimeout(() => {
    mutate()
    retryCountRef.current += 1
  }, 1000)

  // 依赖变化/组件卸载时自动清理定时器
  return () => clearTimeout(timer)
}, [data, mutate])

方案2:SWR原生动态轮询配置(更推荐)

SWR的refreshInterval配置项支持传入函数,可直接根据返回的响应数据动态决定轮询间隔,返回0代表停止轮询。内部已经处理了定时器创建、清理、请求去重等逻辑,无需手动管理副作用:

const { data } = useSWR<IGetAnalysis>(key, fetcher, {
  // 目标字段不存在时1秒轮询一次,存在则停止轮询
  refreshInterval: (data) => typeof data?.simularityJson.analyzes === "undefined" ? 1000 : 0,
  // 可选配置:请求出错时是否继续轮询
  refreshWhenError: true,
  // 可选配置:页面切到后台时是否继续轮询
  refreshWhenHidden: false
})

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 03:15:03