使用 Next.js 设置
推荐的文件结构
我们推荐使用这样的文件结构,尽管 tRPC 不会强制执行。这是您在 我们的示例 中看到的。本页面的其余部分将引导您完成将 tRPC 添加到此结构的过程。
graphql
.├── prisma # <-- if prisma is added│ └── [..]├── src│ ├── pages│ │ ├── _app.tsx # <-- add `withTRPC()`-HOC here│ │ ├── api│ │ │ └── trpc│ │ │ └── [trpc].ts # <-- tRPC HTTP handler│ │ └── [..]│ ├── server│ │ ├── routers│ │ │ ├── _app.ts # <-- main app router│ │ │ ├── post.ts # <-- sub routers│ │ │ └── [..]│ │ ├── context.ts # <-- create app context│ │ └── trpc.ts # <-- procedure helpers│ └── utils│ └── trpc.ts # <-- your typesafe tRPC hooks└── [..]
graphql
.├── prisma # <-- if prisma is added│ └── [..]├── src│ ├── pages│ │ ├── _app.tsx # <-- add `withTRPC()`-HOC here│ │ ├── api│ │ │ └── trpc│ │ │ └── [trpc].ts # <-- tRPC HTTP handler│ │ └── [..]│ ├── server│ │ ├── routers│ │ │ ├── _app.ts # <-- main app router│ │ │ ├── post.ts # <-- sub routers│ │ │ └── [..]│ │ ├── context.ts # <-- create app context│ │ └── trpc.ts # <-- procedure helpers│ └── utils│ └── trpc.ts # <-- your typesafe tRPC hooks└── [..]
将 tRPC 添加到现有的 Next.js 项目
1. 安装依赖项
- npm
- yarn
- pnpm
- bun
npm install @trpc/server@next @trpc/client@next @trpc/react-query@next @trpc/next@next @tanstack/react-query@latest zod
yarn add @trpc/server@next @trpc/client@next @trpc/react-query@next @trpc/next@next @tanstack/react-query@latest zod
pnpm add @trpc/server@next @trpc/client@next @trpc/react-query@next @trpc/next@next @tanstack/react-query@latest zod
bun add @trpc/server@next @trpc/client@next @trpc/react-query@next @trpc/next@next @tanstack/react-query@latest zod
Next.js 集成实际上是我们 React Query 集成 和一些 Next.js 特定集成的组合。
2. 启用严格模式
如果您想使用 Zod 进行输入验证,请确保您已在 tsconfig.json
中启用了严格模式
tsconfig.jsondiff
"compilerOptions": {+ "strict": true}
tsconfig.jsondiff
"compilerOptions": {+ "strict": true}
如果严格模式过于严格,您至少需要启用 strictNullChecks
tsconfig.jsondiff
"compilerOptions": {+ "strictNullChecks": true}
tsconfig.jsondiff
"compilerOptions": {+ "strictNullChecks": true}
3. 创建 tRPC 路由器
使用 initTRPC
函数在 src/server/trpc.ts
中初始化您的 tRPC 后端,并创建您的第一个路由器。我们将在这里创建一个简单的“hello world”路由器和过程 - 但有关创建 tRPC API 的更深入信息,您应该参考
- the 快速入门指南 和 后端使用文档 获取 tRPC 信息
- the Next.js 适配器文档 用于在您的 Next.js 服务器中安装 tRPC。
查看示例后端
server/trpc.tsts
import { initTRPC } from '@trpc/server';// Avoid exporting the entire t-object// since it's not very descriptive.// For instance, the use of a t variable// is common in i18n libraries.const t = initTRPC.create();// Base router and procedure helpersexport const router = t.router;export const procedure = t.procedure;
server/trpc.tsts
import { initTRPC } from '@trpc/server';// Avoid exporting the entire t-object// since it's not very descriptive.// For instance, the use of a t variable// is common in i18n libraries.const t = initTRPC.create();// Base router and procedure helpersexport const router = t.router;export const procedure = t.procedure;
server/routers/_app.tsts
import { z } from 'zod';import { procedure, router } from '../trpc';export const appRouter = router({hello: procedure.input(z.object({text: z.string(),}),).query((opts) => {return {greeting: `hello ${opts.input.text}`,};}),});// export type definition of APIexport type AppRouter = typeof appRouter;
server/routers/_app.tsts
import { z } from 'zod';import { procedure, router } from '../trpc';export const appRouter = router({hello: procedure.input(z.object({text: z.string(),}),).query((opts) => {return {greeting: `hello ${opts.input.text}`,};}),});// export type definition of APIexport type AppRouter = typeof appRouter;
pages/api/trpc/[trpc].tsts
import * as trpcNext from '@trpc/server/adapters/next';import { appRouter } from '../../../server/routers/_app';// export API handler// @link https://trpc.node.org.cn/docs/v11/server/adaptersexport default trpcNext.createNextApiHandler({router: appRouter,createContext: () => ({}),});
pages/api/trpc/[trpc].tsts
import * as trpcNext from '@trpc/server/adapters/next';import { appRouter } from '../../../server/routers/_app';// export API handler// @link https://trpc.node.org.cn/docs/v11/server/adaptersexport default trpcNext.createNextApiHandler({router: appRouter,createContext: () => ({}),});
4. 创建 tRPC 钩子
使用 createTRPCNext
函数从 API 的类型签名创建一组强类型钩子。
utils/trpc.tstsx
import { httpBatchLink } from '@trpc/client';import { createTRPCNext } from '@trpc/next';import type { AppRouter } from '../server/routers/_app';function getBaseUrl() {if (typeof window !== 'undefined')// browser should use relative pathreturn '';if (process.env.VERCEL_URL)// reference for vercel.comreturn `https://${process.env.VERCEL_URL}`;if (process.env.RENDER_INTERNAL_HOSTNAME)// reference for render.comreturn `http://${process.env.RENDER_INTERNAL_HOSTNAME}:${process.env.PORT}`;// assume localhostreturn `http://localhost:${process.env.PORT ?? 3000}`;}export const trpc = createTRPCNext<AppRouter>({config(opts) {return {links: [httpBatchLink({/*** If you want to use SSR, you need to use the server's full URL* @link https://trpc.node.org.cn/docs/v11/ssr**/url: `${getBaseUrl()}/api/trpc`,// You can pass any HTTP headers you wish hereasync headers() {return {// authorization: getAuthCookie(),};},}),],};},/*** @link https://trpc.node.org.cn/docs/v11/ssr**/ssr: false,});
utils/trpc.tstsx
import { httpBatchLink } from '@trpc/client';import { createTRPCNext } from '@trpc/next';import type { AppRouter } from '../server/routers/_app';function getBaseUrl() {if (typeof window !== 'undefined')// browser should use relative pathreturn '';if (process.env.VERCEL_URL)// reference for vercel.comreturn `https://${process.env.VERCEL_URL}`;if (process.env.RENDER_INTERNAL_HOSTNAME)// reference for render.comreturn `http://${process.env.RENDER_INTERNAL_HOSTNAME}:${process.env.PORT}`;// assume localhostreturn `http://localhost:${process.env.PORT ?? 3000}`;}export const trpc = createTRPCNext<AppRouter>({config(opts) {return {links: [httpBatchLink({/*** If you want to use SSR, you need to use the server's full URL* @link https://trpc.node.org.cn/docs/v11/ssr**/url: `${getBaseUrl()}/api/trpc`,// You can pass any HTTP headers you wish hereasync headers() {return {// authorization: getAuthCookie(),};},}),],};},/*** @link https://trpc.node.org.cn/docs/v11/ssr**/ssr: false,});
注意
createTRPCNext
不适用于 tRPC-v9 互操作模式。如果您使用互操作从 v9 迁移,您应该继续使用 初始化 tRPC 的旧方法。
5. 配置 _app.tsx
将您的根应用程序页面包装在 trpc.withTRPC
HOC 中,类似于此
pages/_app.tsxtsx
import type { AppType } from 'next/app';import { trpc } from '../utils/trpc';const MyApp: AppType = ({ Component, pageProps }) => {return <Component {...pageProps} />;};export default trpc.withTRPC(MyApp);
pages/_app.tsxtsx
import type { AppType } from 'next/app';import { trpc } from '../utils/trpc';const MyApp: AppType = ({ Component, pageProps }) => {return <Component {...pageProps} />;};export default trpc.withTRPC(MyApp);
6. 发出 API 请求
您已全部设置!
您现在可以使用刚刚创建的 React 钩子来调用您的 API。有关更多详细信息,请参阅 React Query 集成
pages/index.tsxtsx
import { trpc } from '../utils/trpc';export default function IndexPage() {const hello = trpc.hello.useQuery({ text: 'client' });if (!hello.data) {return <div>Loading...</div>;}return (<div><p>{hello.data.greeting}</p></div>);}
pages/index.tsxtsx
import { trpc } from '../utils/trpc';export default function IndexPage() {const hello = trpc.hello.useQuery({ text: 'client' });if (!hello.data) {return <div>Loading...</div>;}return (<div><p>{hello.data.greeting}</p></div>);}
createTRPCNext()
选项
config
-回调
config
参数是一个函数,它返回一个对象,该对象配置 tRPC 和 React Query 客户端。此函数有一个 ctx
输入,它使您可以访问 Next.js req
对象,以及其他内容。返回值可以包含以下属性
- 必需:
links
用于自定义 tRPC 客户端和 tRPC 服务器之间的数据流。 了解更多。- 可选
queryClientConfig
:用于 tRPC React 钩子内部使用的 React QueryQueryClient
的配置对象: QueryClient 文档queryClient
:一个 React Query QueryClient 实例- 注意:您只能提供
queryClient
或queryClientConfig
。
- 注意:您只能提供
transformer
:应用于传出有效负载的转换器。阅读有关 数据转换器 的更多信息abortOnUnmount
:确定在组件卸载时是否会取消正在进行的请求。默认值为false
。
overrides
: (默认值:undefined
)
ssr
-布尔值 (默认值:false
)
tRPC 在服务器端渲染页面时是否应该等待查询。默认值为 false
。
responseMeta
-回调
能够在服务器端渲染时设置请求标头和 HTTP 状态。
示例
utils/trpc.tstsx
import { createTRPCNext } from '@trpc/next';import type { AppRouter } from '../pages/api/trpc/[trpc]';export const trpc = createTRPCNext<AppRouter>({config(opts) {/* [...] */},});
utils/trpc.tstsx
import { createTRPCNext } from '@trpc/next';import type { AppRouter } from '../pages/api/trpc/[trpc]';export const trpc = createTRPCNext<AppRouter>({config(opts) {/* [...] */},});