'React - TypeError: Cannot read properties of undefined (reading 'params')

So I'm having an error message - TypeError: Cannot read properties of undefined (reading 'params')

TypeError: Cannot read properties of undefined (reading 'params')
       5 | import products from '../products'
       6 | 
       7 | function ProductScreen({ match }) {
       8 |     const product = products.find((p) => p._id == match.params.id)
       9 |     return (
      10 |         <div>
      11 |             {product.name}

This is my ProductScreen.js file where is causing an issue

import React from 'react'
import { Link } from 'react-router-dom'
import { Row, Col, Image, ListGroup, Button, Card } from 'react-bootstrap'
import Rating from '../components/Rating'
import products from '../products'

function ProductScreen({ match }) {
    const product = products.find((p) => p._id == match.params.id)
    return (
        <div>
            {product.name}
        </div>
    )
}

export default ProductScreen

and my App.js

import { Container } from 'react-bootstrap'
import { BrowserRouter as Router, Routes, Route } from 'react-router-dom'
import Header from './components/Header'
import Footer from './components/Footer'

import HomeScreen from './screens/HomeScreen'
import ProductScreen from './screens/ProductScreen'

function App() {
  return (
    <Router>
      <Header />
      <main className="py-3">
        <Container>
          <Routes>
            <Route path='/' element={<HomeScreen/>} exact />
            <Route path='/product/:id' element={<ProductScreen/>} />
          </Routes>
        </Container>
      </main>
      <Footer />
    </Router>
  );
}

export default App;

I also tried to change match.params.id to Number or ParseInt (match.params) and still gave me an error...

I know this is very simple but I'm stuck here and cannot go further... Any help would be appreciated!

One more question - Inside App.js, where Route is, in the tutorial was using components={} attribute instead of element={}. And when I tried the same it gave me an error, so I had to fix it another way. Do you know why it caused an error?

From the tutorial

<Route path='/' component={HomeScreen} exact />

My fix --

<Route path='/' element={<HomeScreen/>} exact />


Solution 1:[1]

The tutorial appears to be older and using react-router-dom version 5 whereas you are using version 6. In version 6 there were many breaking API changes. The Route components no longer use component or render props, the element prop that is passed a valid JSX literal replaced them. route props (history, location, and match) also no longer exist, the routed components must use the React hooks to access them now.

Routes and Route

interface RouteProps {
  caseSensitive?: boolean;
  children?: React.ReactNode;
  element?: React.ReactElement | null;
  index?: boolean;
  path?: string;
}

Given route: <Route path='/product/:id' element={<ProductScreen/>} />

Use the useParams hook to access the id match param. The match param will be a string, so if your product ids are a number type, then to ensure strict equality convert the id param to a number:

import { Link, useParams } from 'react-router-dom';
...

function ProductScreen() {
  const { id } = useParams();
  const product = products.find((p) => p._id === Number(id));
  return (
    <div>
      {product.name}
    </div>
  );
}

Solution 2:[2]

I had the same problem, finally, this code worked.

import { useParams } from 'react-router-dom';

const { id } = useParams();

const product = products.find((p) => p._id === (id));

 <Route path="/product/:id" element={<ProductDetails />} />

Solution 3:[3]

In the Router:

<Route path='/product/:id' element={ProductScreen} />

In the ProductScreen component:

import { useParams } from "react-router-dom";
...
const { id } = useParams();

https://v5.reactrouter.com/web/api/Hooks/useparams

Solution 4:[4]

import { Link, useParams } from 'react-router-dom';
...

function ProductScreen() {
  const { id } = useParams();
  const product = products.find((p) => p._id === Number(id));
  return (
    <div>
      {product.name}
    </div>
  );
}

This solved :)

Solution 5:[5]

**In App.js file:** 

<Route path="/products/:id" element={<SingleProduct />} />

**In SingleProduct.js file:** 

import { useParams } from 'react-router-dom'

const SingleProduct = () => {

const { id } = useParams()
const product = products.find((p) => p._id === (id))

 <div>
      <img src={product.image} alt={product.name} />
      <h3>product.name</h3>
</div>
}
export default SingleProduct;


**This code worked in my case.** 

Solution 6:[6]

import { Link, useParams } from "react-router-dom";
    ...
    
    function ProductScreen() {
      const { id } = useParams();
      const product = products.find((p) => p._id === id);
      return <div>{product.name}</div>;
    }
    
    export default ProductScreen;

Solution 7:[7]

import {useParams} from 'react-router-dom'

const { id } = useParams(); const product = products.find((p) => p._id === (id));

In app.js <Route path="/product/:id" element={} >

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Drew Reese
Solution 2 Syscall
Solution 3 Samorinho
Solution 4 kiri
Solution 5 Md Afsar Uddin
Solution 6 antoniodenaro
Solution 7 Himanshu Dadheech