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

React Query staleTime与动态queryKey使用问题求助

React Query 动态queryKey与staleTime缓存问题解决方案

核心需求实现:缓存已请求过的queryKey数据

要实现「特定queryKey已请求过就直接用缓存、不重复请求」,关键是理清React Query的缓存逻辑和staleTime的作用:

  • 设置staleTime: Infinity:表示对应queryKey的缓存数据永远不会变旧,只要缓存存在,就直接返回缓存值,不会触发后台请求。你之前误以为设置后数据无更新,实际上是切换Producer/Category时,queryKey变成了新的组合(比如["categories", {id: 新ID}]),这是全新的缓存条目,所以会发起新请求;而当再次切回旧ID时,React Query会自动调用对应queryKey的缓存数据,不会重复请求——这正是你需要的行为。
  • 无需手动维护缓存,React Query会自动为每个不同的queryKey单独存储缓存条目。

代码优化点

  1. 移除手动ref缓存逻辑
    你用currentCategoriesRef和currentProducersRef维护initialData完全多余,React Query本身会自动管理缓存。直接删除initialData和onSuccess里的ref赋值代码:
const [categories, producers] = useQueries({
  queries: [
    {
      queryKey: ["categories", { id: currentProducer }],
      queryFn: handleFetchCategories,
      staleTime: Infinity,
      refetchOnMount: false,
      refetchOnWindowFocus: false,
    },
    {
      queryKey: ["producers", { id: currentCategory }],
      queryFn: handleFetchProducers,
      staleTime: Infinity,
      refetchOnMount: false,
      refetchOnWindowFocus: false,
    },
  ],
});
  1. 调整refetch触发配置
    将refetchOnMount设为false,确保组件挂载时,若对应queryKey已有缓存(且未过期),不会重复发起请求。如果后续需要主动刷新缓存,可通过手动调用方法触发。

  2. 类型定义优化
    避免使用any类型,为接口返回数据定义明确的TypeScript类型,提升代码健壮性:

interface Category {
  id: number;
  name: string;
  // 补充其他业务字段
}

const handleFetchCategories = async ({ queryKey }: QueryKey) => {
  const [_, { id }] = queryKey;
  const res = await fetch(`/api/producers/${id}/categories`);
  return res.json() as Promise<Category[]>;
};
  1. 拆分独立useQuery调用
    如果两个查询逻辑相对独立,拆分单独的useQuery调用可提升代码可读性:
const categoriesQuery = useQuery({
  queryKey: ["categories", { id: currentProducer }],
  queryFn: handleFetchCategories,
  staleTime: Infinity,
  refetchOnMount: false,
  refetchOnWindowFocus: false,
});

const producersQuery = useQuery({
  queryKey: ["producers", { id: currentCategory }],
  queryFn: handleFetchProducers,
  staleTime: Infinity,
  refetchOnMount: false,
  refetchOnWindowFocus: false,
});

主动刷新缓存的方法

如果后端数据发生变更,需要主动更新某一queryKey的缓存,可通过queryClient触发:

import { useQueryClient } from '@tanstack/react-query';

const queryClient = useQueryClient();

// 刷新指定Producer的分类缓存
const refreshCategories = (producerId: number) => {
  queryClient.invalidateQueries({ queryKey: ["categories", { id: producerId }] });
};

调用invalidateQueries后,该queryKey的缓存会被标记为失效,下次使用时会重新请求并更新缓存。

内容的提问来源于stack exchange,提问作者Bartosz Król

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 14:35:40