'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.
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();
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 |