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

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

Войти через центр авторизации
Похожие вопросы
26 апр. 2024, в 13:47
1000 руб./за проект
26 апр. 2024, в 13:40
4000 руб./за проект
26 апр. 2024, в 13:39
500 руб./за проект