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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 14:32:19