I have a problem with passing the ${id}
property to my dynamic route [id]>page.jsx
, which is inside the CartItemPage.jsx
file. I'm using the Context API, similar to React, where I store an array of CartItems
and render my Cart with this array. I have a home page and a catalog page, and there are ProductItem
components. When I click on them, I need to navigate the user to CartItemPage[id]
of that specific product, but I'm having trouble getting the id
property.
Here is the code for my CartItem
component (actually a product):
'use client';
import Link from 'next/link';
import styles from './CartItem.module.css';
import { useState, useEffect } from 'react';
import { useAppStore } from '../../app/Context/store';
const CartItem = ({ data }) => {
const [addedToCart, setAddedToCart] = useState(false);
const { addToCart, cartItems } = useAppStore();
useEffect(() => {
if (cartItems.some(cartItem => cartItem.id === data.id)) {
setAddedToCart(true);
} else {
setAddedToCart(false);
}
}, [cartItems]);
const handleAddToCart = data => {
if (cartItems.some(cartItem => cartItem.title === data.title)) {
setAddedToCart(true);
} else {
addToCart(data);
setAddedToCart(true);
console.log(data);
console.log(cartItems);
}
};
return (
<>
<div className={styles.productCard}>
<Link href={`/cartItemPage/${data.id}`}>
<div className='flex items-center flex-col'>
<img className={styles.productImage} src={data.image} alt={data.title} />
<h3 className={styles.productTitle}>{data.title}</h3>
<p className={styles.productPrice}>{data.price} $</p>
{/* Додаткові деталі */}
</div>
</Link>
<button
onClick={() => {
handleAddToCart(data);
}}
className={addedToCart ? styles.addedButton : styles.addButton}
>
{addedToCart ? 'У кошику' : 'До кошику'}
</button>
</div>
</>
);
};
export default CartItem;
here is a code of CartItemPage
, where i created [id] > page.jsx
:
'use client';
import React, { useEffect, useState } from 'react';
import { useRouter, useSearchParams } from 'next/navigation';
import { useAppStore } from '@/app/Context/store';
const CartItemPage = ({ id }) => {
const router = useRouter();
const searchParams = useSearchParams();
const { addToCart, cartItems } = useAppStore();
const [cartItem, setCartItem] = useState(null);
useEffect(() => {
const fetchCartItem = async () => {
try {
const response = await fetch(`https://fakestoreapi.com/products/${id}`);
const data = await response.json(response.data);
setCartItem(data);
} catch (error) {
console.log(error);
}
};
if (id) {
fetchCartItem();
}
}, [id]);
return (
<>
<div>id: {id}</div>
</>
);
};
export default CartItemPage;
You simply have to rename the id
parameter to params
and if you want to refer to the id
just use params.id
.
Like here is your updated code for CartItemPage.jsx
:
Also make sure that the page.js
file for your CartItemPage
is inside a directory called [id]
. So the file structure should be cart > [id] > page.js
.
"use client";
import React, { useEffect, useState } from "react";
import { useRouter, useSearchParams } from "next/navigation";
import { useAppStore } from "@/app/Context/store";
const CartItemPage = ({ params }) => {
const router = useRouter();
const searchParams = useSearchParams();
const { addToCart, cartItems } = useAppStore();
const [cartItem, setCartItem] = useState(null);
useEffect(() => {
const fetchCartItem = async () => {
try {
const response = await fetch(`https://fakestoreapi.com/products/${id}`);
const data = await response.json(response.data);
setCartItem(data);
} catch (error) {
console.log(error);
}
};
if (params.id) {
fetchCartItem();
}
}, [params]);
return (
<>
<div>id: {params.id}</div>
</>
);
};
export default CartItemPage;