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

