React Query API响应未缓存问题排查
React Query缓存不生效问题解决
问题描述
配置了React Query的staleTime和cacheTime,但页面刷新后仍会重新请求数据,缓存未生效,控制台无报错。
已尝试方案
通过设置staleTime和cacheTime实现缓存,但未达到预期效果。
相关代码
App.tsx
import { useQuery } from "react-query"; import { fetchProducts } from "../src/services/api/Api"; function App() { // Fetch the data const { data, isLoading, error } = useQuery("products", fetchProducts, { // Set stale/cache time staleTime: 1000 * 60 * 5, cacheTime: 1000 * 60 * 10, refetchOnWindowFocus: true, }); return ( <> <ChakraProvider> <Container maxW="1200px"> <Header data={data} isLoading={isLoading} error={error} /> <MainTable data={data} isLoading={isLoading} error={error} /> </Container> </ChakraProvider> </> ); } export default App;
API.tsx
import axios from "axios"; export const fetchProducts = async () => { try { const urlEn = "url-here"; const urlFr = "url-here-fr-CA"; // if URL contains /fr, load in FR API // else, load in EN API const urlParts = window.location.pathname.split("/"); const mainUrl = urlParts.includes("fr") ? urlFr : urlEn; const response = await axios.get(mainUrl); const products = response.data.groups; console.log("Fetched data in API component:", products); return products; } catch (error) { console.error("Error:", error); throw error; } };
问题原因
React Query默认缓存存储在内存中,页面刷新时浏览器会清空内存,缓存随之丢失,因此每次刷新都会重新发起请求。staleTime和cacheTime仅控制内存缓存的有效期,无法跨页面刷新保留数据。
另外,当前查询键"products"未区分语言版本,URL切换到法语路径时会覆盖同一键下的缓存数据,也可能导致缓存不符合预期。
解决方案
1. 启用缓存持久化(跨刷新保留缓存)
使用React Query的持久化插件,将缓存存储到localStorage中,确保页面刷新后缓存不丢失。
- 安装依赖:
npm install @tanstack/react-query-persist-client @tanstack/query-sync-storage-persister
- 在项目入口文件(如
main.tsx)中配置持久化:
import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; import { PersistQueryClientProvider } from '@tanstack/react-query-persist-client'; import { createSyncStoragePersister } from '@tanstack/query-sync-storage-persister'; import App from './App'; const queryClient = new QueryClient({ defaultOptions: { queries: { staleTime: 1000 * 60 * 5, // 5分钟内数据视为新鲜 cacheTime: 1000 * 60 * 10, // 10分钟后清理内存缓存 }, }, }); // 创建基于localStorage的持久化器 const persister = createSyncStoragePersister({ storage: window.localStorage, }); ReactDOM.createRoot(document.getElementById('root')!).render( <PersistQueryClientProvider client={queryClient} persistOptions={{ persister }} > <App /> </PersistQueryClientProvider>, );
2. 区分语言版本的查询键
修改useQuery的查询键,加入语言标识,确保不同语言的数据缓存相互独立:
import { useQuery } from "react-query"; import { fetchProducts } from "../src/services/api/Api"; function App() { const urlParts = window.location.pathname.split("/"); const isFrench = urlParts.includes("fr"); // 用包含语言标识的数组作为查询键 const { data, isLoading, error } = useQuery(["products", isFrench], fetchProducts, { refetchOnWindowFocus: true, }); return ( <> <ChakraProvider> <Container maxW="1200px"> <Header data={data} isLoading={isLoading} error={error} /> <MainTable data={data} isLoading={isLoading} error={error} /> </Container> </ChakraProvider> </> ); } export default App;
验证
完成配置后,刷新页面或切换语言路径,React Query会优先从localStorage读取缓存数据,仅当缓存过期或不存在时才发起新请求,控制台不会频繁打印"Fetched data"日志。
内容的提问来源于stack exchange,提问作者jrad09
相关产品推荐
相关产品推荐

