Next.js动态路由报错:无法解构router.query的id属性
解决Next.js App Router动态页面获取路由参数报错问题
问题根源
- 导入路径错误:你把
useRouter的导入路径写成了next/route,正确路径是next/navigation,错误路径会直接触发useRouter is not mounted报错。 - 路由参数加载时机问题:App Router的客户端组件首次渲染时,
router.query可能处于undefined状态——客户端路由信息还未完成初始化,直接解构或访问会抛出TypeError。
解决方案
方案1:修正useRouter用法+条件判断
先修正导入路径,再通过条件判断确保router.query存在后再访问参数:
"use client"; import { useRouter } from "next/navigation"; import { useEffect, useState } from "react"; export default function ShopPage() { const router = useRouter(); const [shopData, setShopData] = useState(null); const [loading, setLoading] = useState(true); useEffect(() => { // 用可选链避免undefined报错 const shopId = router.query?.id; if (shopId) { // 调用API获取店铺数据 fetch(`/api/shops/${shopId}`) .then(res => res.json()) .then(data => { setShopData(data); setLoading(false); }) .catch(err => { console.error("获取数据失败:", err); setLoading(false); }); } }, [router.query]); // 监听query变化 if (loading) return <div>加载中...</div>; if (!shopData) return <div>店铺不存在</div>; return <div>店铺名称:{shopData.name}</div>; }
方案2:直接使用页面props(更推荐)
在App Router的动态页面中,路由参数可以直接作为组件props传入,无需依赖useRouter,这种方式更稳定:
// 不需要"use client"(仅获取参数调用API的话,可直接用服务器组件) export default async function ShopPage({ params }: { params: { id: string } }) { // 直接从params获取id,服务器组件内可异步调用API const res = await fetch(`https://your-api-url/shops/${params.id}`); const shopData = await res.json(); return <div>店铺名称:{shopData.name}</div>; }
注意:如果用服务器组件,无需加
"use client",可直接在组件内异步获取数据,彻底避开客户端路由加载时机的问题。
关键提醒
- 务必确保
useRouter从next/navigation导入,不要写成next/route。 - 客户端组件中操作
router.query时,必须处理undefined的情况,要么用可选链?.,要么加条件判断。 - 能用页面props获取参数的场景,优先用props,比
useRouter更可靠。
内容的提问来源于stack exchange,提问作者Sylwester Zabielski
相关产品推荐
相关产品推荐

