@Daniil161rus

Как сделать, чтобы товары с одинаковыми id показывались в корзине 1 раз?

Нужно сделать так, чтобы товар показывался в корзине только один раз, а цена прибавлялась и появлялось количество товара. Делаю через useContext и 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
  • Вопрос задан
  • 175 просмотров
Решения вопроса 1
ThunderCat
@ThunderCat
{PHP, MySql, HTML, JS, CSS} developer
TL;DR
Завести параметр количество и при добавлении добавлять единичку. Тогда никаких дублирований не будет.
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы