react-query prefetchQuery结合getServerSideProps失效问题求助
问题原因
你的useGetUser钩子使用的queryKey是固定的['useGetUser'],未将用户id纳入其中;同时getServerSideProps预取数据时也使用了相同的固定queryKey。这会引发两个核心问题:
- 不同id的用户查询会共用同一个缓存key,导致数据被覆盖;
- 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
相关产品推荐
相关产品推荐

