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

在Next.js中用TRPC通过动态URL查询单篇文章避免初始报错

解决Next.js客户端路由下TRPC初始加载因router.query.id为空导致的报错问题

在Next.js客户端路由场景下,初始加载时router.query.id会处于未就绪状态(可能是undefined或空对象),直接用类型断言强制转为字符串会触发TRPC请求参数校验失败的报错。以下是几种实用的解决方法:

方法1:通过enabled选项控制查询触发时机

利用TRPC useQuery的enabled配置项,仅当router.query.id有效时才发起请求。这是最推荐的方案,能避免无效请求和报错:

import { useRouter } from "next/router";
import { api } from "~/utils/api";

const SinglePost = () => {
  const router = useRouter();
  // 先判断id是否为有效字符串
  const postId = typeof router.query.id === 'string' ? router.query.id : '';
  
  const { data } = api.post.getById.useQuery(
    { id: postId },
    { 
      // 仅当postId非空时启用查询
      enabled: !!postId 
    }
  );

  return (
    <div>
      {data ? data : '加载中...'}
    </div>
  );
};

export default SinglePost;

方法2:结合router.isReady判断路由就绪状态

Next.js的useRouter提供了isReady属性,标识路由是否已完全解析。可以用它来延迟查询或做条件渲染:

import { useRouter } from "next/router";
import { api } from "~/utils/api";

const SinglePost = () => {
  const router = useRouter();

  if (!router.isReady) {
    return <div>加载中...</div>;
  }

  // 路由就绪后,router.query.id已确保是字符串类型
  const { data } = api.post.getById.useQuery({
    id: router.query.id as string,
  });

  return (
    <div>
      {data}
    </div>
  );
};

export default SinglePost;

方法3:在TRPC后端处理空参数

如果不想在前端做判断,也可以在TRPC的后端路由中添加参数校验,当id为空或无效时返回明确的错误或空数据,避免前端报错:

// 示例:TRPC后端路由定义
export const postRouter = router({
  getById: publicProcedure
    .input(z.string().optional()) // 允许id为空
    .query(async ({ input }) => {
      if (!input) {
        return null; // 或抛出友好错误
      }
      return await prisma.post.findUnique({ where: { id: input } });
    }),
});

这样即使前端初始传递空值,后端也能妥善处理,不会触发报错。

内容的提问来源于stack exchange,提问作者asd man

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 02:23:01