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

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

Похожие вопросы
ITK academy Нижний Новгород
от 50 000 до 90 000 ₽
ITK academy Воронеж
от 50 000 до 90 000 ₽