Answer the question
In order to leave comments, you need to log in
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 };
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
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 questionAsk a Question
731 491 924 answers to any question