D
D
Daniel161rus2021-05-13 13:55:19
React
Daniel161rus, 2021-05-13 13:55:19

How to make products with the same id shown in the cart 1 time?

It is necessary to make sure that the product is shown in the basket only once, and the price is added and the quantity of the product appears. I do it through useContext and useReducer.

CartProvider.js

import { useReducer, createContext, useState } from "react";

const CartContext = createContext();


const reducer = (state, action) => {
  switch (action.type) {
    case "ADD":                           // Добавляет товар
      return [...state, action.item]; 
    break;
    case "DELETE":                      // Удаляет товар
      const newArr = [...state];
      newArr.splice(action.index, 1);
      return newArr;
    break;
    default:
      throw new Error(`unknown action ${action.type}`);
  }
};

const CartProvider = ({ children }) => {
  const [state, dispatch] = useReducer(reducer, []);
  const [popup, setPopup] = useState(false)

  return (
    <CartContext.Provider value={{cart: {state, dispatch}, popup: {popup, setPopup}}}>
      {children}
    </CartContext.Provider>
  );
};

export { CartContext, CartProvider };


PopupCart.jsx

const PopupCart = () => {
  const appData = useContext(AppContext)
  const CartData = useContext(CartContext)
  const items = CartData.cart.state // корзина
  const dispatch = CartData.cart.dispatch
  const totalPrice = items.reduce((total, b) => total+ b.price , 0); //считается цена 
        const popup = CartData.popup.popup
  const setPopup = CartData.popup.setPopup
 
  const handleRemove = index => {
    let count = items.length;
    dispatch({type: "DELETE", index})
    count -= 1
    if (count === 0) {
      setPopup(!popup);
    }		
  }

  if (items.length === 0) {
    return (
      <AnimatePresence>
      {popup && (
        <motion.div
          initial={{ opacity: 0 }}
          animate={{ opacity: 1 }}
          exit={{ opacity: 0 }}
          className="cart-popup"
        >
          <h3 className="cart-popup__title cart-popup__empty">В корзине пусто</h3>
          <a href="/shopping-cart">
            <button className="btn btn_medium cart-popup__empty" style={buttonsStyles}>Перейти в корзину</button>
          </a>
        </motion.div>
      )}
    </AnimatePresence>
    )
  }
  return (
    <AnimatePresence>
      {popup && (
        <motion.div
          initial={{ opacity: 0 }}
          animate={{ opacity: 1 }}
          exit={{ opacity: 0 }}
          className="cart-popup"
        >
          <h3 className="cart-popup__title">В корзине { items.length } товаров на {parseFloat(totalPrice.toFixed(2))} руб</h3>
          {items.map((item, index) => (
            <CartItem key={index} product={item} index={index} handleRemove={handleRemove} items={items}/>
          ))}
          <a href="/shopping-cart">
            <button className="btn btn_medium" style={buttonsStyles}>Перейти в корзину</button>
          </a>
        </motion.div>
      )}
    </AnimatePresence>
  )
}

export default PopupCart

Answer the question

In order to leave comments, you need to log in

1 answer(s)
T
ThunderCat, 2021-05-13
@Daniil161rus

TL;DR
Enter the quantity parameter and add one when adding. Then there will be no duplication.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question