Next.js 13 App Router动态路由传参router.query未定义问题求助
Next.js 13 App Router动态路由router.query未定义问题解决
问题描述
在Next.js 13的App Router环境下,从/experimental页面跳转至动态路由/experimental/${id}时,使用next/navigation的useRouter获取router.query出现未定义错误,无法获取路由参数并展示卡片详情。
问题代码及报错
数据文件draft.js
export const draft = [ { id: 1, title: "Burkina Faso serve Togo Vincent student", imageUrl: "/cards/1.jpg", imageType: "single image", price: 8000, buttonText: "View Design", cardType: "Single Page", popularity: 1, cardCategory: "singlePageCard", }, ]; export default draft;
ExperimentalCard页面
import Cards from "../../components/Cards/Cards"; import { draft } from "../../Data/Draft_Data"; const ExperimentalCard = () => { return ( <div className="ml-[1rem] md:ml-14"> <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-y-10 min-h-[120vh]"> {draft.map((item, index) => ( <Cards key={index} items={item} /> ))} </div> </div> ); }; export default ExperimentalCard;
Cards组件
'use client' import { useRouter } from 'next/navigation' import React from "react"; const Cards = ({ items }) => { const router = useRouter() const handleCardClick = (id) => { router.push(`/experimental/${id}`); }; return ( <div> <div className="mx-5 lg:mx-10"> <div className="w-full h-[30rem] md:h-[25rem] lg:h-[20rem] items-center bg-contain bg-no-repeat" style={{ backgroundImage: `url('${items.imageUrl}')` }} onClick={() => handleCardClick(item.id)} > <div className="bg-[#23272a93] relative z-0 w-32 mb-4 ml-4 h-11 text-center items-center flex rounded-sm justify-center "> <p className="text-base-100 uppercase">{items.cardType}</p> </div> </div> <div className="flex flex-row mt-4 justify-between"> <h2 className="font-normal text-[1.5rem] md:text-[1.4rem] lg:text-xl basis-2/3"> {items.title} </h2> <p className="font-bold text-2xl lg:text-xl basis-1/3 text-right md:text-left lg:text-right"> ৳{items.price} </p> </div> </div> </div> ); }; export default Cards;
动态路由[id]/page.jsx
'use client' import { useRouter } from 'next/navigation' import React from 'react' const Page = () => { const router = useRouter(); const { id } = router.query; return ( <div> <h1>Experimental Card Details</h1> <p>Card ID: {id}</p> <p>Card title: {title}</p> <p>Card imageUrl: {imageUrl}</p> <p>Card imageType: {imageType}</p> <p>Card price: {price}</p> <p>Card buttonText: {buttonText}</p> <p>Card cardType: {cardType}</p> <p>Card popularity: {popularity}</p> <p>Card cardCategory: {cardCategory}</p> </div> ); } export default Page
报错信息
Unhandled Runtime Error TypeError: Cannot destructure property 'id' of 'router.query' as it is undefined. src\app\experimental\[id]\page.jsx (7:10) @ id 5 | const Page = () => { 6 | const router = useRouter(); > 7 | const { id } = router.query; | ^
解决方案
1. 修正动态路由页面的参数获取方式
App Router中,动态路由参数无需通过useRouter.query获取,官方推荐直接通过组件的params props接收。同时从数据文件中匹配对应ID的卡片数据,渲染详情:
修改后的[id]/page.jsx:
import { draft } from "../../../Data/Draft_Data"; const CardDetailPage = ({ params }) => { const { id } = params; // 将字符串ID转为数字匹配数据 const card = draft.find(item => item.id === parseInt(id)); if (!card) { return <div>卡片不存在</div>; } return ( <div> <h1>Experimental Card Details</h1> <p>Card ID: {card.id}</p> <p>Card title: {card.title}</p> <p>Card imageUrl: {card.imageUrl}</p> <p>Card imageType: {card.imageType}</p> <p>Card price: ৳{card.price}</p> <p>Card buttonText: {card.buttonText}</p> <p>Card cardType: {card.cardType}</p> <p>Card popularity: {card.popularity}</p> <p>Card cardCategory: {card.cardCategory}</p> </div> ); }; export default CardDetailPage;
2. 修正Cards组件的点击事件参数错误
原Cards组件中点击事件传递的是item.id,但组件接收的props名为items,导致传递undefined,修正为items.id:
修改后的Cards组件关键部分:
// ... 其他代码不变 <div className="w-full h-[30rem] md:h-[25rem] lg:h-[20rem] items-center bg-contain bg-no-repeat" style={{ backgroundImage: `url('${items.imageUrl}')` }} onClick={() => handleCardClick(items.id)} {/* 修正此处参数 */} > // ... 其他代码不变
原因说明
- App Router中,
useRouter的query在客户端组件初始渲染阶段可能还未完成路由参数的加载,因此会出现undefined的情况,而通过paramsprops获取参数是更可靠的方式。 - Cards组件的参数传递错误会导致跳转时路由ID为undefined,进一步加剧了详情页的参数获取问题。
内容的提问来源于stack exchange,提问作者Auvee
相关产品推荐
相关产品推荐

