React Query技术咨询:请求返回4**或5**错误时如何复用缓存资源
回答
当然可以实现这个需求!React Query本身就有非常灵活的缓存控制机制,刚好能满足你这种「服务器/网络波动时用缓存兜底」的场景,下面给你两种常用的实现方式:
方式一:利用React Query默认缓存行为(最简单)
React Query的默认逻辑就是:当你发起新的请求失败时,之前成功缓存的数据不会被清除。也就是说,useQuery返回的data字段依然会保留上次成功获取的缓存值,同时error字段会被赋值。
你只需要在组件里做个简单判断:优先使用data(不管有没有error),只有当data不存在且有error时,再展示错误状态。示例代码:
const { data, error, isLoading } = useQuery(['your-resource-key'], fetchYourResource, { // 可选:设置重试次数,让React Query自动重试几次请求,降低单次失败的影响 retry: 3, // 可选:设置数据新鲜时间,这段时间内不会自动发起重新请求,减少不必要的请求 staleTime: 300000, // 5分钟 }); if (isLoading && !data) { return <Loading />; } // 优先展示缓存数据,即使请求失败 if (data) { return <YourDataComponent data={data} />; } // 只有完全没有缓存数据且请求失败时,才展示错误 if (error) { return <ErrorComponent error={error} />; }
这种方式不需要复杂配置,完全利用React Query的默认缓存特性,适合大多数场景。
方式二:自定义查询函数,失败时直接返回缓存数据
如果你希望在查询函数层面就直接返回缓存(不让error状态触发),可以借助queryClient手动获取缓存数据,在请求失败时兜底返回:
import { useQuery, useQueryClient } from '@tanstack/react-query'; const YourComponent = () => { const queryClient = useQueryClient(); const queryKey = ['your-resource-key']; const fetchWithCacheFallback = async () => { try { const response = await fetch('/your-api-endpoint'); if (!response.ok) { throw new Error(`HTTP error! status: ${response.status}`); } const data = await response.json(); return data; } catch (error) { // 请求失败时,尝试从缓存获取数据 const cachedData = queryClient.getQueryData(queryKey); if (cachedData) { return cachedData; } // 如果缓存也没有,再抛出错误 throw error; } }; const { data, error, isLoading } = useQuery(queryKey, fetchWithCacheFallback, { retry: 3, }); // 后续的渲染逻辑可以简化,因为失败时已经返回缓存了 if (isLoading) return <Loading />; if (error) return <ErrorComponent error={error} />; return <YourDataComponent data={data} />; };
这种方式更激进,直接让查询函数在失败时返回缓存,组件层面几乎感知不到错误(除非缓存也不存在),适合对错误状态控制更严格的场景。
额外提示
- 如果你希望在后台悄悄重试失败的请求,可以保持
refetchOnError为默认的true,这样React Query会在后台自动重试,成功后更新缓存和UI,用户完全无感知。 cacheTime配置可以设置缓存的保留时间,默认是5分钟,如果你希望缓存更持久,可以适当调大。
内容的提问来源于stack exchange,提问作者kioopi
相关产品推荐
相关产品推荐

