Reputation: 17
I am able to get all products to show when mapping from API, but when I try to get a single item to show, I get nothing displayed. When I look at the network tag in dev tools, it shows the specific item was successfully requested, but nothing renders.
(The main screen that maps everything works fine)
import React, { useState, useEffect } from 'react'
import Product from '../components/Product'
import { Row, Col } from 'react-bootstrap'
import axios from 'axios'
const HomeScreen = () => {
const [products, setProducts] = useState([])
useEffect(() => {
const fecthProducts = async () => {
const { data } = await axios.get('/api/products')
setProducts(data)
}
fecthProducts()
}, [])
return (
<>
<h1>Jewelry</h1>
<Row>
{products.map((product) => (
<Col key={product.id} sm={12} md={6} lg={4} xl={3}>
<Product product={product} />
</Col>
))}
</Row>
</>
)
}
export default HomeScreen
(this is the single product page where)
import { Link, useParams } from 'react-router-dom'
import {
Row,
Col,
Image,
ListGroup,
ListGroupItem,
Button
} from 'react-bootstrap'
import axios from 'axios'
const ProductScreen = () => {
const [product, setProduct] = useState([])
const { id } = useParams()
useEffect(() => {
const fetchProduct = async () => {
const { data } = await axios.get(`/api/products/${id}`)
setProduct(data)
}
fetchProduct()
}, [id])
return (
<>
<Link className="btn btn-light my-3" to="/">
GO BACK
</Link>
<Row>
<Col md={4}>
<div>
<Image src={product.image} alt={product.name} fluid rounded />
</div>
</Col>
<Col md={3}>
<ListGroup>
<ListGroupItem>
<h4>{product.name}</h4>
<h5>${product.price}</h5>
</ListGroupItem>
<ListGroupItem>{product.description}</ListGroupItem>
<ListGroupItem>
{product.inStock > 0 ? 'In Stock' : 'Out of Stock'}
</ListGroupItem>
<ListGroupItem>
<Button
className="btn-block"
type="button"
disabled={product.inStock === 0}
>
Add to Cart
</Button>
</ListGroupItem>
</ListGroup>
</Col>
</Row>
</>
)
}
export default ProductScreen
The picture below shows how the ProductScreen page renders
https://i.sstatic.net/PJKpa.png
Upvotes: 1
Views: 147
Reputation: 396
product
in your case is an aray
of one element, use the code below instead :
useEffect(() => {
const fetchProduct = async () => {
const { data } = await axios.get(`/api/products/${id}`)
setProduct(data[0])
}
fetchProduct()
}, [id])
Upvotes: 0
Reputation: 87
In product state, you are storing the Array of objects not a single object please get the result something like in render function
product && product[0] && product[0].name
and same like other values change according to the properties.
Upvotes: 1