rize
rize

Reputation: 29

How to keep previous states when adding new ones

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

Answers (1)

Dennis Vash
Dennis Vash

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

Related Questions