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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.23 09:23:13