Нужно сделать так, чтобы товар показывался в корзине только один раз, а цена прибавлялась и появлялось количество товара. Делаю через 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