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
相关产品推荐
相关产品推荐

