如果在不指定参数的情况下使某个键失效,会强制进行一次完整的缓存刷新吗?

前端开发 2026-07-12

请看下列情况:

const useFetchPosts = (params?: Record<string, string>) => {
  async function fetchPosts({
    queryKey,
  }: {
    queryKey: [string, Record<string, string> | undefined];
  }) {
    const [, params] = queryKey;

    let url = new URL("http://localhost:8080/api/post");

    if (params) {
      Object.entries(params).forEach(([key, value]) => {
        if (key === "category") {
          url = new URL("http://localhost:8080/api/post/category");
        } else {
          url = new URL("http://localhost:8080/api/post/search");
        }
        url.searchParams.append(key, value);
      });
    }

    const response = await fetch(url, { credentials: "include" });
    if (!response.ok) throw new Error("Network response was not ok");

    return response.json();
  }

  const { status, data, error } = useQuery({
    queryKey: ["posts", params],
    queryFn: fetchPosts,
    staleTime: Infinity,
  });

  return { status, data, error };
};

假设我想使某个筛选的结果失效。通常是在每次创建新帖子时就会这样做。如果我只使键 posts 失效而不指定 params,这会强制刷新整个缓存吗?

解决方案

是的,使 ["posts"] 失效也会使以 ["posts", ...] 开头的所有查询失效,包括你筛选出的查询。

在你的钩子(hook)里,查询键的结构是这样的:

queryKey: ["posts", params]

这意味着缓存里可能包含如下条目:

  • ["posts", undefined]
  • ["posts", { category: "tech" }]
  • ["posts", { search: "react" }]

如果你执行:

queryClient.invalidateQueries({
  queryKey: ["posts"],
});

默认情况下,TanStack Query执行的是 前缀匹配(即 exact: false)。

因此这将使以下失效:

  • ["posts"]
  • ["posts", { category: "tech" }]
  • ["posts", { search: "react" }]
  • 以及任何以 "posts" 开头的查询

这将刷新整个「posts」缓存组。

如果你只想使基础查询失效,你需要:

queryClient.invalidateQueries({
  queryKey: ["posts"],
  exact: true,
});

那只会使以下失效:

  • ["posts"]

并且不会影响筛选出的查询。

站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。

相关文章