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
相关产品推荐
相关产品推荐

