Home > OS >  Route to specific product details page from mapped product list
Route to specific product details page from mapped product list

Time:12-09

My App.js

import React, {useState} from 'react';
import Dropdown from './components/Dropdown/Dropdown';
import Header from './components/Header/Header.jsx'
import {BrowserRouter as Router, Routes, Route } from "react-router-dom";
import Navbar from './components/Navbar/Navbar';
import Footer from './components/Footer/Footer';
import Main from './pages/Main';
import Catalog from './pages/Catalog';
import About from './pages/About';
import Contacts from './pages/Contacts';
import CarProductDetails from './components/СarItems/CarProductDetails';
import Error from './pages/Error'


function App() {
  const [dropState, setDropState] = useState(false);
  const handleCloseDrop = () => setDropState(false);
  const handleOpenDrop = () => setDropState(true);

  return (
    <>
<Router>
    <Header openDrop={handleOpenDrop}/>
    <Navbar />
    <Dropdown showDrop={dropState} closeDrop={handleCloseDrop} />
    <Routes>
      <Route path='/' element={<Main />} />
      <Route path='/about' element={<About />} />
      <Route path='/contacts' element={<Contacts />} />
      <Route path='/catalog' element ={<Catalog />} />
      <Route path='/catalog/:productId' element={<CarProductDetails />}/>
      <Route path='*' element={<Error />} />
    </Routes>
    <Footer /> 
</Router>
  </>
  );
}

export default App;

My ProductPage

const CarSectionItem = () => {
    return (
      carsData.map((product) => (
      <CarItem key={product.id}>
        //*some code*//
        <CarButtonLink to={`/catalog/${product.id}`} target="_blank">
          {product.buttonLabel}
        </CarButtonLink>
      </CarItem>
      ))
    )


};
export default CarSectionItem;

Component that includes Car Item with other components:

import React from "react";
import { CarsSectionContainer, CarsContainer } from "./CarsSectionElements";
import CarsFilter from "./CarsFilter/CarsFilter";
import CarSectionItem from "./СarSectionItem/CarSectionItem";


const CarsSection = () => {


  return (
    <CarsSectionContainer>
      <CarsFilter/>
      <CarsContainer>
        <CarSectionItem />
      </CarsContainer>
    </CarsSectionContainer>
  );
};

export default CarsSection;

My ProductItemDetails



import React, { useState } from "react";
import carsData from "../data/CarsData";
import { useParams } from "react-router-dom";


const CarProductDetails = () => {
  // const [thumbsSwiper, setThumbsSwiper] = useState(null);
  const { productId } = useParams();
  const thisProduct = carsData.find((product) => product.id === productId);
  return (
    <div>
    <h1>{thisProduct.title}</h1>
    <h1>{thisProduct.price}</h1>
    </div>

  );
}
export default CarProductDetails;

My Data File

const carsData = [
  {
    id: 1,
    price: '$80 000',
    brand: 'Genesis',
    title: "text",
  },
  {
    id: 2,
    price: '$80 000',
    brand: 'Toyota',
    title: "text1",
  },
  {
    id: 3,
    price: '$80 000',
    brand: 'Hyundai',
    title: "text2",
  },
];

export default carsData;

I'm trying to map product items in my product list and get a specific link for each of product opened on a new page.

But when i click on the button it gives me an error:

Uncaught TypeError: Cannot read properties of undefined (reading 'brand')
The above error occurred in the <CarProductDetails> component:
Uncaught TypeError: Cannot read properties of undefined (reading 'brand')

I was following these guides: https://codesandbox.io/s/react-router-product-detail-pages-dynamic-links-tmcjc?file=/src/App.js and https://www.youtube.com/watch?v=oVE6cx3UEpM but it doesn't work for me.

What should i do differently?

CodePudding user response:

I think problem in CarProductDetails component.

When you get url params from useParams hook, it's always be string. See docs, type declaration section.

And in CarProductDetails component, you're trying to compare productId (type string) with product.id (type number) with strong equal operator (===). As a result, you got undefined.

Try to change your compare function to this one:

const thisProduct = carsData.find((product) => product.id === parseInt(productId));

  • Related