reactjsreact-router-dom

Unable to receive props from Parent Element


Have a parent component Products and another component SingleProduct.

I am trying to pass a product as a prop to SingleProduct but getting undefined when I console.log.

Can anyone tell me what I'm doing wrong?

Also tried passing the props using UseState but still getting undefined.

import data from "../data"

const Products = () => {
    const products = data;

    return (
        <div className='pt-12 grid gap-4 md:grid-cols-2 lg:grid-cols-3 '>
            {products.map((prod) => {
                return (
                    <Link to={`/product/${prod.id}`}>
                        <SingleProduct product={prod}></SingleProduct>
                    </Link>
                )
            })}
            <Link to='/home'></Link>
        </div>
    )
}

export default Products
const SingleProduct = ({ product }) => {
    console.log(product)

    return (
        <div>
            <figure className='px-4 pt-4'>
                <img
                    src={prod.image}
                    alt='Elf'
                    className='rounded-xl h-64 md:h-48 w-full object-cover'
                />
            </figure>
        </div>
    )
}

export default SingleProduct

App.jsx

const router = createBrowserRouter([
  {
    path: '/',
    element: <Products></Products>,
  },
  {
    path: '/product/:id',
    element: <SingleProduct></SingleProduct>,
  },
])

function App() {
  return (
    <RouterProvider router={router}></RouterProvider>
  )
}

export default App

Solution

  • You are using the SingleProduct component twice.

    First time you are mapping the products inside Products component and creating links that has SingleProduct inside them and then passing the prod to the component which is fine.

    But for the second time you are using this component as an element for the /product/:id path where you don't pass any product to it which means the product is undefined.

    What you can do is to make another component just for the route that shows inside the /product/:id and then import data and then find data based on the id of the URL like this:

    const SingleProductPage = () => {
    let { id } = useParams();
    const [product, setProduct] = useState();
    
    useEffect(() => {
      id && setProduct(data.find((prod) => prod.id == id))
    }, [id]) // runs whenever the id changed and updates the product
    
    return product ? <SingleProduct product={product} /> : null
    }
    
    export default SingleProductPage;