0

I am building a shopping cart which should have the number of cart items automatically updated on the top right corner. Currently the number comes from localStorage, so the page must be reloaded in order to see it working. I need it updated automatically so I think the State is the best approach, but have no idea how to use in this case.

I have created a State in single item (ProductItem component) which is updated for every action "Add to cart".

The current structure is: Home (with CartButton) > Products > ProductItem

How can I pass the single State (ProductItem) to the up level (Products), sum up all single components states, then pass it again to up level (Home), then finally pass as a prop to CartButton?

How can I achieve that? Any help would be greatly appreaciated.

Structure

enter image description here

ProductItem.jsx

import PropTypes from 'prop-types';
import React from 'react';
import { Link } from 'react-router-dom';

class ProductsItem extends React.Component {
  constructor() {
    super();

    this.state = {
      qtyState: 1,
    };
  }

  addCart = () => {
    const {
      title,
      thumbnail,
      price,
      id,
      available,
    } = this.props;

    this.setState((prevState) => ({ qtyState: prevState.qtyState + 1 }));

    const cart = localStorage.cart ? JSON.parse(localStorage.cart) : [];

    cart.push({
      title,
      thumbnail,
      price,
      id,
      qtd: 1,
      available,
    });
    localStorage.setItem('cart', JSON.stringify(cart));
  }

  render() {
    const {
      title,
      thumbnail,
      price,
      id,
    } = this.props;

    return (
      <div>
        <p>{title}</p>
        <img src={ thumbnail } alt={ title } />
        <p>{ `$ ${price}` }</p>
        <button type="button" onClick={ this.addCart }>Add to Cart</button>
      </div>
    );
  }
}

ProductsItem.propTypes = {
  title: PropTypes.string,
  thumbnail: PropTypes.string,
  id: PropTypes.string,
  price: PropTypes.number,
  available: PropTypes.number,
}.isRequired;

export default ProductsItem;

Kelson Batista
  • 406
  • 4
  • 25

3 Answers3

2

You should use a context to share data between component. Here is one of my answer to another post with a clean example on how to use the context API from React.

Quentin Grisel
  • 4,794
  • 1
  • 10
  • 15
1

Yes, I also had the same kind of problem. You can solve this problem by using any of the following:

  1. React Context API (https://reactjs.org/docs/context.html)
  2. Redux (https://redux-toolkit.js.org/)

I like redux, but context is easy to get started with so you can use that, so whenever you add an item to the cart your context state would update and show the updated state count on the cart icon.

Ahmed Gad
  • 691
  • 1
  • 7
  • 26
zillBoy
  • 81
  • 2
  • 5
1

There are three ways

(As mentioned by "zillBoy")

  1. React context API
  2. Redux

(One addition)

  1. You can pass callback function from Home to Product and another callback from Product to ProductItem. (passing data from child to parent component - react - via callback function)
Paveloosha
  • 563
  • 2
  • 6
  • 15