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

Next.js中getServerSideProps调用prefetchInfiniteQuery返回undefined正常吗

问题原因
  • prefetchInfiniteQuery 返回undefined属于正常设计:该方法为无返回值的异步方法,仅负责将请求到的数据写入QueryClient缓存,不会直接返回查询结果。如果需要同时获取预取结果,可替换为fetchInfiniteQuery方法。
  • 你当前的代码未完整实现React Query的SSR hydration逻辑,存在三处核心错误:
    1. _app.js 中全局声明QueryClient实例,服务端渲染时会在所有请求间共享实例,导致数据串用、内存泄漏问题,且未添加Hydrate组件注入脱水后的缓存数据。
    2. getServerSideProps中未实际调用prefetchInfiniteQuery将数据写入缓存,而是手动拼接了providers分页结构,没有走React Query的缓存逻辑。
    3. 未将dehydrate(queryClient)生成的脱水状态作为根级props返回给页面,导致客户端无法拿到服务端预取的缓存数据。
解决方案

1. 修正_app.js的配置

将QueryClient实例改为组件内部初始化,新增Hydrate组件注入服务端返回的缓存状态:

import { QueryClientProvider, QueryClient, Hydrate } from 'react-query';
import { useState } from 'react';

MyApp ({ Component, pageProps, user_account_menu, userProfile, token, fallback }){
  // 保证每个请求/客户端实例拥有独立的QueryClient
  const [queryClient] = useState(() => new QueryClient())
  return (
    <>
      <DefaultSeo {...SEO}/>
      <FacebookPixel />
      <SWRConfig value={{ fallback }}>
        <ThemeProvider theme={theme}>
          <GlobalStyles />
          <BreakPointProvider>
          <AuthProvider>
          <DisplayProvider>
          <EcommerceProvider>
            <QueryClientProvider client={queryClient}>
              {/* 注入服务端预取的缓存数据 */}
              <Hydrate state={pageProps.dehydratedState}>
                <Header 
                  principal_menu={fallback.principal_menu}  
                  menu_sections={fallback.menu_sections}
                  user_account_menu={user_account_menu}
                  token={token} 
                  userProfile={userProfile} 
                />
                <Component {...pageProps} token={token} reviews={fallback.reviews}  newsletter={fallback.newsletter}/>
              </Hydrate>
            </QueryClientProvider>
            <PopUpNewsletter newsletter={fallback.newsletter} />
            <Footer footer_menu={fallback.footer_menu} reviews={fallback.reviews} policies={fallback.policies_menu}/>
          </EcommerceProvider>
          </DisplayProvider>
          </AuthProvider>
          </BreakPointProvider>
        </ThemeProvider>
      </SWRConfig>
    </>
  )
}

2. 修正getServerSideProps的预取逻辑

调用prefetchInfiniteQuery将第一页数据写入缓存,将脱水后的缓存状态作为props返回:

export async function getServerSideProps(ctx) {
  const queryClient = new QueryClient()
  const { query } = ctx;
  const { page = 1 } = query;
  const token = parseCookies(ctx).jwt ? parseCookies(ctx).jwt : null
  const limit = 16;
  const start = +page === 1 ? 0 : (+page - 1) * limit
  const configSimple = 'simple'

  // 预取无限查询第一页数据,queryKey必须和客户端useInfiniteQuery的queryKey完全一致
  await queryClient.prefetchInfiniteQuery(
    ['providers', token], // 替换为你客户端实际使用的queryKey
    ({ pageParam = 0 }) => {
      if(!token){
        return fetchAPI(getTalentCards);
      }else{
        return fetchAuthorizationAPI(getTalentCards, token, configSimple);
      }
    },
    {
      // 配置项和客户端useInfiniteQuery的配置保持一致即可
      staleTime: 1000 * 60 * 5,
    }
  )

  // 其他普通接口预取用prefetchQuery即可,示例:
  const providerTypesData = await queryClient.fetchQuery(['provider_types'], () => fetchAPI(/* 你的请求地址 */))
  const countriesData = await queryClient.fetchQuery(['countries'], () => fetchAPI(/* 你的请求地址 */))
  const citiesData = await queryClient.fetchQuery(['cities'], () => fetchAPI(/* 你的请求地址 */))
  const providerStatusesData = await queryClient.fetchQuery(['provider_statuses'], () => fetchAPI(/* 你的请求地址 */))

  return {
    props: {
      dehydratedState: dehydrate(queryClient), // 核心:返回脱水后的缓存
      page: +page,
      provider_types: providerTypesData,
      countries: countriesData,
      cities: citiesData,
      provider_statuses: providerStatusesData,
      start,
      limit,
      token: token
    }
  }
}

3. 客户端侧适配

确保页面中useInfiniteQuery的queryKey、查询函数、配置项和服务端预取时的参数完全一致,不需要额外接收props里的providers数据,初始化即可直接拿到服务端预取的第一页数据。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 03:24:04