Home > Blockchain >  Problem in using useReducer and useContext hooks to make a shopping cart
Problem in using useReducer and useContext hooks to make a shopping cart

Time:05-23

I'm trying to make a shopping cart using the useReducer and useContext hook but I'm facing an issue.When I click on Add button I want products to be displayed one under another in the Cart screen but when I add the products in the cart, are not displayed. I don't know what I'm doing wrong. Here is my homepage file where I listed the products :

import React, { useEffect, useReducer, useContext } from 'react';
import '../components/components.css';
import axios from 'axios';
import logger from 'use-reducer-logger';
import { Store } from '../Store';

const reducer = (state, action) => {
  switch (action.type) {
    case 'FETCH_REQUEST':
      return { ...state, loading: true };
    case 'FETCH_SUCCESS':
      return { ...state, products: action.payload, loading: false };
    case 'FETCH_FAIL':
      return { ...state, loading: false, error: action.payload };
    default:
      return state;
  }
};

const Products = () => {
  const [{ loading, error, products, product }, dispatch] = useReducer(
    logger(reducer),
    {
      products: [],
      product: [],
      loading: true,
      error: '',
    }
  );

  //const [products, setProducts] = useState([]);
  useEffect(() => {
    const fetchData = async () => {
      dispatch({ type: 'FETCH_REQUEST' });
      try {
        const result = await axios.get('/api/products');
        dispatch({ type: 'FETCH_SUCCESS', payload: result.data });
      } catch (err) {
        dispatch({ type: 'FETCH_FAIL', payload: err.message });
      }

      //setProducts(result.data);
    };
    fetchData();
  }, []);

  const { state, dispatch: ctxDispatch } = useContext(Store);
  const { cart } = state;
  const addToCartHandler = () => {
    const existItem = cart.cartItems.find((x) => x._id === product.id);
    const quantity = existItem ? existItem.quantity   1 : 1;

    ctxDispatch({
      type: 'CART_ADD_ITEM',
      payload: { ...product, quantity },
    });
  };

  return (
    <div className="produse">
      {products.map((item) => (
        <div className="produs" key={item._id}>
          <div>
            <img className="imagine-produs" src={item.image} alt={item.name} />
          </div>

          <div>
            <h3 className="nume-produs">{item.name} </h3>
          </div>
          <div className="pret-produs">{item.price} RON</div>

          <div>
            <button className="adauga-produs" onClick={addToCartHandler}>
              Adauga
            </button>
          </div>
        </div>
      ))}
    </div>
  );
};
export default Products;

and here is my cart component:

import React, { useContext } from 'react';
import '../components/components.css';
import { Store } from '../Store';

const Cart = () => {
  const { state, dispatch: ctxDispatch } = useContext(Store);
  const {
    cart: { cartItems },
  } = state;

  console.log(cartItems);

  return (
    <div className="cart-items">
      <h1 className="cart-items-header">Produsele din cos</h1>
      <div className="clear-cart">
        {cartItems.length >= 1 && (
          <button className="clear-cart-button">Sterge produse</button>
        )}
      </div>
      {cartItems.length === 0 && (
        <div className="cart-items-empty"> Nu sunt produse adaugate.</div>
      )}
      <div>
        {cartItems.map((item) => (
          <div key={item._id} className="cart-items-list">
            <img
              className="cart-items-image"
              src={item.image}
              alt={item.name}
            />

            <div className="cart-items-name">{item.name}</div>
            <div>
              <button className="cart-items-add"> </button>
              <button className="cart-items-remove">-</button>
            </div>
            <div className="cart-items-price">
              {item.quantity} * {item.price} RON
            </div>
          </div>
        ))}
      </div>
      <div className="cart-items-total-price-name">
        <div className="cart-items-total-price"> RON</div>
      </div>
    </div>
  );
};

export default Cart;

here is the entire project: https://github.com/burNN11/newProject . If somebody can give me a tip it would be nice

CodePudding user response:

in my think, existItem is going to be changed as following:

const addToCartHandler = (item) => {
    const existItem = cart.cartItems.find((x) => x._id === item.id);
    const quantity = existItem ? existItem.quantity   1 : 1;

    ctxDispatch({
      type: 'CART_ADD_ITEM',
      payload: { ...item, quantity },
    });
 };
 ...
};

CodePudding user response:

you have some issue with your logic in the dispatch to add to cart I made the respective modifications:

 const addToCartHandler = (item) => {
    const existItem = cart.cartItems.find((x) => x._id === item.id);
    const quantity = existItem ? existItem.quantity   1 : 1;

    ctxDispatch({
      type: 'CART_ADD_ITEM',
      payload: { ...item, quantity },
    });
  };

  return (
    <div className="produse">
      {products.map((item) => (
        <div className="produs" key={item._id}>
          <div>
            <img className="imagine-produs" src={item.image} alt={item.name} />
          </div>

          <div>
            <h3 className="nume-produs">{item.name} </h3>
          </div>
          <div className="pret-produs">{item.price} RON</div>

          <div>
            <button className="adauga-produs" onClick={()=>addToCartHandler(item)}>
              Adauga
            </button>
          </div>
        </div>
      ))}
    </div>
  );
};

Be aware that in order to be able to run it locally I needed to drop logger

  • Related