Unable to recieve id and consume it using useParams. Page showing blank in react

Viewed 303

I have two pages one with a list of products which are rendering fine but when i click any of them it is taking me to route with id but with blank page. My product Details page is not able to consume the id and render the items. There is something wrong but I am not able to find it. How do i solve this?

App.js
<Routes>
 <Route path="/" element={<Products />}></Route>
 <Route path="/:id" element={<ProductDetails />}></Route> 
</Routes>

Products Page
{items && items.map(({ id, name,price, desc, small, large }) => (
                <Grid item xs={6} xs={12} sm={6} md={3} >
                  <Link to={`/${id}`}>
                  <Card key={id}>
                    <div>
                      <h2>{name}</h2>
                      <h3>Rs {price}</h3>
                    </div>
                  </Card>
                  </Link>
                </Grid>
              ))}


Product Details Page
function ProductDetail() {
    const [singleProduct, setSingleProduct] = useState({})
    const { id } = useParams()
    const findProduct = () => {
      setSingleProduct(data.find((product) => product.id === id))
    }

    useEffect(() => {
        findProduct()
    }, [id])

    
    return (
        <section>
        <img src={singleProduct.large} alt="" />
        <h1>
          {singleProduct.name}
        </h1>
        </section>
)}
1 Answers

Since the routes look correct and I see no reason why the id param wouldn't defined I believe this is a type-mismatch issue where the route param is a string type and the product.id is not a string type.

Use a type-safe comparison when searching the data by converting the product.id to a string.

Example:

const { id } = useParams();

const findProduct = () => {
  setSingleProduct(data.find((product) => String(product.id) === id))
}

And as I pointed out in a comment, there's no need to use any local state, just find the data and render directly.

Example:

function ProductDetail() {
  const { id } = useParams();
  const singleProduct = data.find((product) => String(product.id) === id)) || {};

  return (
    <section>
      <img src={singleProduct.large} alt="" />
      <h1>{singleProduct.name}</h1>
    </section>
  );
}
Related