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

Next.js动态路由中无法获取点击组件ID的问题排查

动态路由无法捕获产品ID的问题排查与解决

在Next.js项目中,主页面Home组件通过外部API获取产品数据并按分类展示,点击产品通过Link组件跳转至products/[id]页面,但在[id].jsx文件中无法正确捕获点击产品的ID。

相关代码

Home组件代码

'use client'

import Product from "@/components/product"
import { useQuery } from "@tanstack/react-query"
import axios from "axios"
import Link from "next/link"

const Home = () => {

  const {data,isLoading,error} = useQuery({
    queryKey: ['products'],

    queryFn: async () => {
      const res = await axios.get(
        'https://fakestoreapi.com/products'
      )
      const data = await res.data
      if(data){
        console.log(data);
        return data
      }
    }
  })

  if(isLoading) return "Your content is Loading..."

  if(error) return "There was an error" + error.message

  if(data){
    
    // Organize and sort the data based on categories
      const organizedData = data ? data.reduce((acc, item) => {
        const category = item.category;
        if (!acc[category]) {
          acc[category] = []
        }
        acc[category].push(item)
        return acc
    }, {})
    : {}

    return(
      <section className='flex-col'>
      <div className="bg-black w-full flex flex-col justify-center items-center text-yellow-100 h-[45vh] sm:h-[55vh] mt-8">
        <h1 className='text-5xl'>OnlineStore</h1>
        <h2 className='text-xl'>Buy Everything you need</h2>
      </div>
      <section className="padding p-8"> 
        <h2>Discover Our Products</h2>
        {Object.entries(organizedData).map(([category, categoryData]) => (
          <div key={category} className="py-5">
            <h3 className="uppercase text-xl">{category}</h3>
            <div className="grid grid-cols-1 md:grid-cols-3 lg:grid-cols-4 xl:grid-cols-5 place-items-center gap-8 mt-5">
            {categoryData.map((product)=> {
              return(
                  <Link key={product.id} href={`products/${product.id}`}>
                    <Product
                      key={product.id} 
                      id= {product.id}
                      img={product.image} 
                      title={product.title} 
                      price={product.price}
                    />
                  </Link>
              )
            })}
            </div>
          </div>
        ))}
      </section>
    </section>
    )
  }
  return null
}

export default Home

[id].jsx代码(原错误版本)

'use client'

import { useRouter } from "next/navigation";


const ProductPage = () => {
  const router = useRouter()
  const { id } = router.push
  console.log(id)

  return(
    <div>
      <h1>Product Details</h1>
      <p>Product ID: {id}</p>
    </div>
  )

}


export default ProductPage;

问题原因

你错误地尝试从router.push中解构id,但push是useRouter提供的页面跳转方法,并非路由参数的存储位置。在Next.js 13+的App Router中,客户端组件需要通过useParams()钩子来获取动态路由参数。

修正后的[id].jsx代码

'use client'

import { useParams } from "next/navigation";

const ProductPage = () => {
  const params = useParams()
  // 动态路由参数默认是字符串,若需要数字类型可转换:const productId = Number(params.id)
  const { id } = params
  console.log(id)

  return(
    <div>
      <h1>Product Details</h1>
      <p>Product ID: {id}</p>
    </div>
  )
}

export default ProductPage;

说明

  1. 导入useParams钩子:从next/navigation中引入useParams,它专门用于在客户端组件中获取动态路由的参数。
  2. 获取并解构参数:调用useParams()获取包含所有动态参数的对象,从中解构出id。
  3. 参数类型处理:动态路由参数默认是字符串类型,如果你的业务需要数字ID,可以通过Number(id)进行类型转换。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 18:23:24