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

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的情况,而通过params props获取参数是更可靠的方式。
  • Cards组件的参数传递错误会导致跳转时路由ID为undefined,进一步加剧了详情页的参数获取问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 10:49:55