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

tRPC在Next.js中经getServerSideProps获取数据后仍重复请求问题

问题:Next.js + tRPC + react-query 服务端预取数据后客户端重复请求

我在Next.js项目中使用tRPC做后端调用,希望在getServerSideProps里通过tRPC获取数据并传入页面组件,同时用react-query管理全局状态。相关配置与代码如下:

1. _app.tsx 中的 withTRPC 配置

export default withTRPC<AppRouter>({
  config({ ctx }) {
    const url = `${getBaseUrl()}/api/trpc`;
    return {
      url,
      transformer: superjson,
      queryClientConfig: { defaultOptions: { queries: { staleTime: 60 } } },
    };
  },
  ssr: false,
})(MyApp);

设置ssr: false是因为Next.js的一个bug,若设为true会导致首次渲染返回空props。

2. 页面的 getServerSideProps 函数

export const getServerSideProps = async () => {
  const ssg = createSSGHelpers({
    router: appRouter,
    ctx: await createContext(),
    transformer: superjson,
  });

  const entryRD = await getPageBySlug(option.some("trados"))();
  await ssg.prefetchQuery("contentful.getProductList");

  console.log("==>props", entryRD, ssg.dehydrate());

  return {
    props: {
      trpcState: ssg.dehydrate(),
      entryRD,
    },
  };
};

服务端日志显示entryRD和ssg.dehydrate()均有值,且脱水数据包含正确获取的查询数据。

3. 页面组件代码

const Page = ({ entryRD, trpcState }: InferGetServerSidePropsType<typeof getServerSideProps>) => {
  const { data, isLoading } = trpc.useQuery(["contentful.getProductList"]);

  console.log("==>data", data, isLoading);
  return isLoading ? <div>Loading...</div> : <EntryCompontn entry={entryRD} />
};

按照文档理解,服务端获取数据后脱水返回缓存,组件使用trpc.useQuery应直接读取缓存值,但实际data为空、isLoading短暂为true,数据会重新请求。请问是理解有误还是操作出错?


解决方法

核心问题是你没有把服务端脱水的trpcState注入到客户端的QueryClient中,导致客户端无法识别服务端预取的缓存数据。

步骤1:在_app.tsx中注入脱水状态

修改withTRPC的配置,从页面props中读取trpcState并作为QueryClient的初始状态:

export default withTRPC<AppRouter>({
  config({ ctx, pageProps }) {
    const url = `${getBaseUrl()}/api/trpc`;
    return {
      url,
      transformer: superjson,
      queryClientConfig: { 
        defaultOptions: { queries: { staleTime: 60 } },
        // 注入服务端脱水的状态
        initialState: pageProps.trpcState
      },
    };
  },
  ssr: false,
})(MyApp);

步骤2:确认页面props传递逻辑

确保getServerSideProps返回的trpcState能被_app.tsx的pageProps接收——Next.js默认会把页面getServerSideProps返回的props传递给_app的pageProps参数,无需额外处理。

额外注意事项

  • 若后续Next.js修复了导致ssr: true返回空props的bug,建议改回ssr: true,tRPC的SSG/SSR模式会自动处理数据的脱水与注水,无需手动管理trpcState。
  • 确保createSSGHelpers使用的ctx与客户端tRPC的上下文逻辑一致,避免出现权限校验、数据源不一致等问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.21 20:48:45