Reputation: 29
I'm making a cart component where a user can add/delete products in a cart. Each time a button (Add to Cart) is clicked, the product should be added to the cart. When I try adding different types of products, the state resets each time to whatever product I clicked. But when I add multiple of the same product, the state updates accordingly, showing the product the same amount of times I had clicked. I need to be able to add different types of products to the cart. Any help is appreciated!
Displaying products on page:
export default function Products(props) {
const [cartItems, setCartItems] = useState([]);
//access first image from imageURLs section in object
const image = props.img;
const obj = {};
const result = Object.assign(obj, image);
//update cart
function addToCart(item) {
const updateCart = [...cartItems, props];
updateCart.forEach((e) => console.log("foreach", e));
setCartItems(updateCart);
}
console.log("new state", cartItems);
return (
<div className="product-container">
<img src={result[0]} alt="furniture" className="image" />
<div className="product-info">
<div className="product-name">{props.name}</div>
<div className="product-brand">{props.brand}</div>
<div className="product-price">${props.price}</div>
<button
type="submit"
className="add-button"
onClick={() => addToCart({ ...props })}
>
+ Add to Cart
</button>
</div>
</div>
);
}
Parent component:
import { useState } from "react";
import "../styles/Home.scss";
import "../styles/Products.scss";
import Products from "./Products";
export default function Home() {
const [product, setProduct] = useState([]);
//get product info from api
async function getProducts(e) {
e.preventDefault();
const data = await fetch(
`https://main-api.fulhaus.com/fulhaus-tech-test/get-products`
)
.then((res) => res.json())
.then((data) => data);
//set state for products
setProduct(data);
}
//display product info on page
function displayProduct() {
const productToDisplay = [
...new Set(
product.map((product, index) => (
<Products
key={product._id}
id={product._id}
img={product.imageURLs}
name={product.vendorProductName}
brand={product.vendorName}
price={product.MSRP}
/>
))
),
];
return productToDisplay;
}
return (
<div>
<div className="home-container"></div>
<div className="home-title">
<h1>Patio Furniture</h1>
<button
type="submit"
className="home-button"
onClick={(e) => getProducts(e)}
>
SHOP
</button>
</div>
<div className="product-section">{displayProduct()}</div>
</div>
);
}
Upvotes: 0
Views: 86
Reputation: 53964
The state resets since you remount the components on every render by invoking the displayProduct
function on every render:
<div>{displayProduct()}</div>
Instead you should rewrite the logic to mount it once, the Set
object is useless here (it contains objects, which you can't apply uniqueness to):
export default function Home() {
const [product, setProduct] = useState([]);
//get product info from api
async function getProducts(e) {
e.preventDefault();
const data = await fetch(
`https://main-api.fulhaus.com/fulhaus-tech-test/get-products`
)
.then((res) => res.json())
.then((data) => data);
//set state for products
setProduct(data);
}
return (
<div>
<div className="home-container"></div>
<div className="home-title">
<h1>Patio Furniture</h1>
<button
type="submit"
className="home-button"
onClick={(e) => getProducts(e)}
>
SHOP
</button>
</div>
<div className="product-section">
{product.map((product, index) => (
<Products
key={product._id}
id={product._id}
img={product.imageURLs}
name={product.vendorProductName}
brand={product.vendorName}
price={product.MSRP}
/>
))}
</div>
</div>
);
}
Upvotes: 1