Home > OS >  ProductScreen.js:12 Uncaught (in promise) TypeError: Cannot read properties of undefined (reading &#
ProductScreen.js:12 Uncaught (in promise) TypeError: Cannot read properties of undefined (reading &#

Time:12-01

im running into a problem and no matter how much research/googling i do, i cant seem to fix this issue, been dealing with this error for last 2 days, first i tried to find any answer online someone else might have had but i cant seem to figure it out, so now i need to ask someone more experienced as to what im doing wrong, please take a look at my error and code pictures and see if you might catch something i cant... tunnel vision..

frontend is reactjs and backend is node/express

when i open up home screen page, every product loads from the backend, no issue, but once i click onto single product to try and get that specific product page with unique id, initial skeleton loads for a brief moment without having any of the products information, before crashing with following error

"Unhandled Rejection (TypeError): Cannot read properties of undefined (reading 'params')"

now i have tried different solutions and ways to go around that, checked if the issue might with react-router-dom(useParams), backend server/api(get request and find single product) or the frontend side of fetching single product via axios, but since im doing the same thing on HomeScreen page while fetching all products with axios, i cant figure out why it might not work with single product, im using useState and useEffect to fetch single product from the backend api.

here is single product screen, the fetch part of it at least

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

const ProductScreen = ({ match }) => {
const [product, setProduct] = useState({})

useEffect(() => {
    const fetchProduct = async () => {
        const { data } = await axios.get(`/api/products/${match.params.id}`)
        setProduct(data)
    }

    fetchProduct()
}, [match])

server file

const express = require('express')
const products = require('./data/products')

const app = express()

app.get('/', (req, res) => {
res.send('API is running...')
})

app.get('/api/products', (req, res) => {
res.json(products)
})

app.get('/api/products/:id', (req, res) => {
const product = products.find((p) => p._id === req.params.id)
res.json(product)
})

app.js file

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

   const 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

thanks in advance

CodePudding user response:

It looks like you're trying to access route params within your ProductScreen component through props. React Router v6 does not pass props to elements...

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

From the migration guide...

Using elements instead of components means we don't have to provide a passProps-style API so you can get the props you need to your elements.

To access route params, use the params hook

// ...
import { useParams } from "react-router-dom";

const ProductScreen = () => {
  const [product, setProduct] = useState({})
  const { id } = useParams()

  useEffect(() => {
    const fetchProduct = async () => {
      const { data } = await axios.get(`/api/products/${encodeURIComponent(id)}`)
      setProduct(data)
    }

    fetchProduct()
  }, [ id ])
  • Related