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

react-query prefetchQuery结合getServerSideProps失效问题求助

问题原因

你的useGetUser钩子使用的queryKey是固定的['useGetUser'],未将用户id纳入其中;同时getServerSideProps预取数据时也使用了相同的固定queryKey。这会引发两个核心问题:

  1. 不同id的用户查询会共用同一个缓存key,导致数据被覆盖;
  2. React Query无法匹配预取缓存与客户端查询——客户端查询虽key相同,但queryFn依赖的id是动态值,React Query会判定为不同查询,最终不会读取脱水后的缓存,造成dehydratedState.queries为空。
解决方案

1. 修改自定义钩子的queryKey,加入id参数

更新useGetUser,将id作为queryKey的一部分,确保每个用户的查询拥有唯一标识:

export const useGetUser = (id: number) => {
  return useQuery<User, Error>(
    ['useGetUser', id], // 新增id到queryKey中
    () => Api.getUser(id),
    {
      retry: false,
      refetchOnWindowFocus: false,
      enabled: !!id,
    },
  );
};

2. 同步修改预取数据的queryKey

在getServerSideProps中,预取时使用包含id的queryKey,保证与客户端钩子的queryKey完全一致:

export const getServerSideProps: GetServerSideProps = async ({ query }) => {
  const { id } = query;
  // 校验id有效性,避免转换为NaN
  const userId = Number(id);
  if (isNaN(userId)) {
    return { notFound: true };
  }
  
  const queryClient = new QueryClient();
  await queryClient.prefetchQuery(['useGetUser', userId], () =>
    Api.getUser(userId),
  );
  return {
    props: {
      dehydratedState: dehydrate(queryClient),
      id: userId,
    },
  };
};

额外检查点

  • 确认Api.getUser能正常返回数据(若预取时Promise失败,该查询不会被加入缓存);
  • 保证客户端与服务端的QueryClient配置一致(默认配置通常即可满足需求)。

修改后,预取的缓存数据会被客户端useGetUser正确识别,dehydratedState.queries将包含对应查询条目,客户端也不会重复发起请求。

内容的提问来源于stack exchange,提问作者skwFE

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 15:15:16