Search code examples
reactjsreact-props

Cannot add item to cart when click on the button


When i click on the cart symbol, it changes its value to be in cart but actually my product is not rendered on the cart component, is there something wrong or missing in my code, please help me to fix it! Thank you so much!

Context.js:

class ProductProvider extends React.Component {
  state = {
    products: storeProducts,
    detailProduct: detailProduct,
    cart: [],
    modalOpen: false,
    modalProduct: detailProduct
  };

  getItem = (id) => {
    const product = this.state.products.find((item) => item.id === id);
    return product;
  };

  addToCart = (id) => {
    console.log("add to cart");
    let tempProducts = [...this.state.products];
    const index = tempProducts.indexOf(this.getItem(id));
    const product = tempProducts[index];
    product.inCart = true;
    product.count = 1;
    const price = product.price;
    product.total = price;

    this.setState(() => {
      return (
        { products: tempProducts, cart: [...this.state.cart, product] },
        () => console.log(this.state)
      );
    });
  };

  openModal = (id) => {
    const product = this.getItem(id);
    this.setState(() => {
      return { modalProduct: product, openModal: true };
    });
  };

  closeModal = (id) => {
    this.setState(() => {
      return { modalOpen: false };
    });
  };

Cart.js:

import React from "react";
import CartColumns from "./CartColumns";
import CartList from "./CartList";
import EmptyCart from "./EmptyCart";

import { ProductContext } from "../App";

export default class Cart extends React.Component {
  render() {
    return (
      <div>
        <ProductContext.Consumer>
          {(value) => {
            console.log(value, "inside Product COnt");
            if (value.length > 0) {
              return (
                <div>
                  <CartColumns />
                  <CartList items={items} />
                </div>
              );
            } else {
              <EmptyCart />;
            }
          }}
        </ProductContext.Consumer>
      </div>
    );
  }
}

CartList.js:

import React from "react";
import CartItem from "./CartItem";

export default function CartList(props) {
  const { items } = props;

  return (
    <div>
      {items.cart.map((item) => (
        <CartItem
          key={item.id}
          item={item}
          increment={item.increment}
          decrement={item.decrement}
        />
      ))}
    </div>
  );
}

CartItem.js:

import React from "react";

function CartItem(props) {
  const { id, title, img, price, total, count } = props.item;
  const { increment, decrement, removeItem } = props;

  return (
    <div className="row my-1 text-capitalize text-center">
      <div className="col-10 mx-auto col-lg-2">
        <img
          src={img}
          style={{ width: "5rem", heigth: "5rem" }}
          className="img-fluid"
          alt=""
        />
      </div>
      <div className="col-10 mx-auto col-lg-2 ">
        <span className="d-lg-none">product :</span> {title}
      </div>
      <div className="col-10 mx-auto col-lg-2 ">
        <strong>
          <span className="d-lg-none">price :</span> ${price}
        </strong>
      </div>
      <div className="col-10 mx-auto col-lg-2 my-2 my-lg-0 ">
        <div className="d-flex justify-content-center">
          <div>
            <span className="btn btn-black mx-1">-</span>
            <span className="btn btn-black mx-1">{count}</span>
            <span className="btn btn-black mx-1">+</span>
          </div>
        </div>
      </div>
      <div className="col-10 mx-auto col-lg-2 ">
        <div className=" cart-icon">
          <i className="fas fa-trash" />
        </div>
      </div>

      <div className="col-10 mx-auto col-lg-2 ">
        <strong>item total : ${total} </strong>
      </div>
    </div>
  );
}

export default CartItem;

Sandbox link for better observation:https://codesandbox.io/s/cart-code-addict-forked-l6tfm?file=/src/cart/CartItem.js


Solution

  • There were few issues

    Change following

    this.setState(() => {
        return (
            { products: tempProducts, cart: [...this.state.cart, product] },
            () => console.log(this.state)
        );
    });
    

    to

    this.setState(
        {
            products: tempProducts,
            cart: [...this.state.cart, product]
        },
        () => console.log(this.state)
    );
    

    And need to use value.cart to check for length and when passing as a prop.

    Instead of

    if (value.length > 0) {
        return (
            <div>
                <CartColumns />
                <CartList items={items} />
            </div>
        );
    }
    

    It should be

    if (value.cart.length > 0) {
        return (
            <div>
                <CartColumns />
                <CartList items={value.cart} />
            </div>
        );
    }
    

    And in CartList,

    Instead of

    {
        items.cart.map(item => (
            <CartItem
                key={item.id}
                item={item}
                increment={item.increment}
                decrement={item.decrement}
            />
        ));
    }
    

    it should be

    {
        items.map(item => (
            <CartItem
                key={item.id}
                item={item}
                increment={item.increment}
                decrement={item.decrement}
            />
        ));
    }
    

    Now it shows the cart with items

    Code sandbox => https://codesandbox.io/s/cart-code-addict-forked-c3kug?file=/src/cart/CartList.js