NextJS App Router调用TRPC useMutation遇类型错误求助
解决TRPC useMutation 类型错误问题
1. 检查TRPC客户端初始化配置
确保在App Router中使用createTRPCReact正确初始化客户端(App Router场景推荐用这个而非createTRPCNext):
// app/trpc/client.ts import { createTRPCReact } from '@trpc/react-query'; import type { AppRouter } from '@/server/trpc/routers/_app'; export const trpc = createTRPCReact<AppRouter>();
然后在根布局用TRPCReactProvider完成包裹:
// app/layout.tsx import { trpc } from '@/app/trpc/client'; import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; import { httpBatchLink } from '@trpc/client'; const queryClient = new QueryClient(); export default function RootLayout({ children }: { children: React.ReactNode }) { return ( <html lang="zh-CN"> <body> <QueryClientProvider client={queryClient}> <trpc.Provider client={trpc.createClient({ links: [ httpBatchLink({ url: '/api/trpc', }), ], })} > {children} </trpc.Provider> </QueryClientProvider> </body> </html> ); }
2. 验证路由定义正确性
确认你的等待列表接口是用mutation()方法定义的,而非其他类型:
// server/trpc/routers/waitlist.ts import { z } from 'zod'; import { publicProcedure, router } from '../trpc'; export const waitlistRouter = router({ addEmail: publicProcedure .input(z.object({ email: z.string().email() })) .mutation(async ({ input }) => { // 写入数据库逻辑示例 await db.waitlist.create({ data: { email: input.email } }); return { success: true }; }), });
同时根路由要正确合并子路由:
// server/trpc/routers/_app.ts import { router } from '../trpc'; import { waitlistRouter } from './waitlist'; export const appRouter = router({ waitlist: waitlistRouter, }); export type AppRouter = typeof appRouter;
3. 规范页面中useMutation的调用方式
客户端页面必须加上'use client'指令,然后通过TRPC实例正确调用:
// app/page.tsx 'use client'; import { trpc } from '@/app/trpc/client'; import { useState } from 'react'; export default function Home() { const [email, setEmail] = useState(''); const addToWaitlist = trpc.waitlist.addEmail.useMutation({ onSuccess: () => { alert('邮箱已加入等待列表'); setEmail(''); }, onError: (err) => { console.error(err); }, }); return ( <div> <input type="email" value={email} onChange={(e) => setEmail(e.target.value)} placeholder="输入你的邮箱" /> <button onClick={() => addToWaitlist.mutate({ email })} disabled={addToWaitlist.isLoading} > {addToWaitlist.isLoading ? '提交中...' : '加入等待列表'} </button> </div> ); }
4. 校验依赖版本兼容性
确保@trpc/client、@trpc/react-query、@trpc/server和@tanstack/react-query版本一致,版本不匹配极易引发类型错误。查看package.json示例:
{ "dependencies": { "@trpc/client": "^10.45.0", "@trpc/react-query": "^10.45.0", "@trpc/server": "^10.45.0", "@tanstack/react-query": "^5.17.19" } }
若版本不一致,执行npm install或pnpm install更新到匹配版本。
5. 清除缓存并重启TS服务
TypeScript缓存可能导致类型识别异常,执行以下操作:
- 重启VS Code的TS服务器(快捷键:Ctrl+Shift+P → 选择"TypeScript: Restart TS Server")
- 删除
.next文件夹和node_modules/.cache文件夹 - 重新运行
npm run dev
内容的提问来源于stack exchange,提问作者19jmrs
相关产品推荐
相关产品推荐

