Search code examples
next.jsnext.js13nextjs-dynamic-routing

Not getting the id of the clicked component in nextjs dynamic routing


As the name suggests, i cant seem to figure out dynamic routing in my project. I have a Home component(which is the main page of my project) where I've fetched the data from an external api and used map to display them. Basically, what i want to do is: when user clicks on any product item, they should be redirect to the corresponding products/:[id] page.

I have implemented the dynamic routing by using Link from next/Link. But i can't seem to catch the id of the clicked product in my products/[id].jsx file.

Here's my Home component code:

'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

and, here's my [id].jsx code

'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;

Can someone look at this and tell me what am i doing wrong?


Solution

  • You can get the params by destructuring it in your [id].jsx file as follows:

    'use client'
    
    import { useRouter } from "next/navigation";
    
    
    const ProductPage = ({params}) => {
      const router = useRouter()
      const { id } = params
      console.log(id)
    
      return(
        <div>
          <h1>Product Details</h1>
          <p>Product ID: {id}</p>
        </div>
      )
    
    }
    
    
    export default ProductPage;