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

React中如何在保留SWR自动刷新能力的同时手动修改返回数据

报错原因

你之前的代码出现无限重渲染报错,是因为直接在组件渲染流程中调用setStatus,每次状态更新都会触发组件重渲染,重渲染后又会再次执行if(data) setStatus(data.status)逻辑,陷入无限循环。

以下是两个可保留SWR 5秒自动刷新能力、同时支持手动修改展示值的可行方案:


方案1:用useEffect同步SWR数据到本地状态

通过useEffect监听SWR返回的data.status变化,只有该值实际更新时才同步到本地状态,避免无限循环,本地状态独立于SWR缓存,手动修改仅影响当前组件展示:

import useSWR from 'swr'
import { useState, useEffect } from 'react'

// 你的fetcher实现
const fetcher = (url) => fetch(url).then(res => res.json())

function YourComponent() {
  const { data, error } = useSWR('fetchData', fetcher, { refreshInterval: 5000 })
  const [status, setStatus] = useState('')

  // 仅当SWR返回的data.status变化时,才同步到本地状态
  useEffect(() => {
    if (data?.status) {
      setStatus(data.status)
    }
  }, [data?.status])

  const changeStatus = () => {
    // 手动修改仅更新本地状态,不影响SWR缓存和自动刷新逻辑
    setStatus('bad')
  }

  if (error) return <p>加载失败</p>
  if (!data) return <p>加载中...</p>

  return (
    <>
      <p>{status}</p>
      <button onClick={changeStatus}>change status</button>
    </>
  )
}

方案2:直接修改SWR缓存(无需额外维护state)

SWR自带的mutate方法可以直接修改对应key的缓存数据,修改会全局生效到所有使用该SWR key的组件,无需额外声明本地状态:

import useSWR from 'swr'

const fetcher = (url) => fetch(url).then(res => res.json())

function YourComponent() {
  const { data, error, mutate } = useSWR('fetchData', fetcher, { refreshInterval: 5000 })

  const changeStatus = () => {
    // 第一个参数为新的缓存数据,第二个参数传false表示不立即重新发起请求
    mutate({...data, status: 'bad'}, false)
  }

  if (error) return <p>加载失败</p>
  if (!data) return <p>加载中...</p>

  return (
    <>
      <p>{data.status}</p>
      <button onClick={changeStatus}>change status</button>
    </>
  )
}

方案选择建议

  • 仅需要在当前组件临时修改展示值,选方案1
  • 需要修改在所有用到该接口数据的组件都生效,选方案2

两个方案都不会影响SWR原有的5秒自动刷新逻辑,每次接口返回新数据后都会覆盖手动修改的值。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 13:45:03