我已经创建了一个swiggy克隆,我正在处理购物车菜单和购物车,但每当我添加新的东西到购物车它的改变购物车中的所有项目的价格我如何停止呢?每一个项目应该得到它的价格.我知道我做了一些错误的切片逻辑请帮助我与此.
cartSlice.js
import { createSlice } from "@reduxjs/toolkit";
const savedCart = JSON.parse(localStorage.getItem("cart")) || {};
const cartSlice = createSlice({
name: "cart",
initialState: {
items: savedCart.items || [],
totalPrice: savedCart.totalPrice || 0,
discountPrice: savedCart.discountPrice || 0,
deliveryFees: savedCart.deliveryFees || 0,
price: savedCart.price || 0,
},
reducers: {
addItem: (state, action) => {
const existingItemIndex = state.items.findIndex(
(item) => item.card.info.id === action.payload.card.info.id
);
if (existingItemIndex !== -1) {
state.items[existingItemIndex].count += 1;
} else {
state.items.push({ card: action.payload.card, count: 1 });
}
state.price =
action.payload.card.info.price / 100 ||
action.payload.card.info.defaultPrice / 100;
state.totalPrice +=
action.payload.card.info.price / 100 ||
action.payload.card.info.defaultPrice / 100;
state.discountPrice = (state.price * 10) / 100;
state.deliveryFees = (state.price * 5) / 100;
console.log(state.price);
// localStorage.setItem("cart", JSON.stringify(state.items));
},
removeItem: (state, action) => {
const itemIdToRemove = action.payload.card.info.id;
const itemIndexToRemove = state.items.filter(
(item) => item.card.info.id === itemIdToRemove
);
if (itemIndexToRemove !== -1) {
state.items.splice(itemIndexToRemove, 1);
}
// localStorage.setItem("cart", JSON.stringify(state));
},
clearCart: (state) => {
state.items.length = 0;
},
decreaseItemCart: (state, action) => {
const { id } = action.payload;
const itemToDecrease = state.items.find(
(item) => item.card.info.id === id
);
state.price = state.totalPrice;
if (itemToDecrease && itemToDecrease.count > 1) {
itemToDecrease.count -= 1;
state.price = state.price * itemToDecrease.count;
state.discountPrice = (state.price * 10) / 100;
state.deliveryFees = (state.price * 2) / 100;
console.log(state.price);
}
},
increaseItemCart: (state, action) => {
state.price = state.totalPrice;
const { id } = action.payload;
const itemToIncrease = state.items.find(
(item) => item.card.info.id === id
);
if (itemToIncrease) {
itemToIncrease.count += 1;
state.price = state.price * itemToIncrease.count;
state.discountPrice = (state.price * 10) / 100;
state.deliveryFees = (state.price * 2) / 100;
console.log(state.price);
}
},
},
});
export default cartSlice.reducer;
export const {
addItem,
removeItem,
clearCart,
decreaseItemCart,
increaseItemCart,
} = cartSlice.actions;
字符串
cart.js
import { CARD_IMG } from "../utils/constants";
import { useDispatch, useSelector } from "react-redux";
import {
removeItem,
decreaseItemCart,
increaseItemCart,
clearCart
} from "../store/cartSlice";
import React from "react";
const Cart = () => {
const CartItem = useSelector((store) => store.cart.items);
const dispatch = useDispatch();
const totalPrice = useSelector((store) => store.cart.totalPrice);
const discountPrice = useSelector((store) => store.cart.discountPrice);
const deliveryFees = useSelector((store) => store.cart.deliveryFees);
const price = useSelector((store) => store.cart.price);
console.log("price in cart", price);
const finalAmount = price + deliveryFees - discountPrice;
const handleDecreaseItem = (menuItem) => {
dispatch(decreaseItemCart({ id: menuItem.card.info.id }));
};
const handleIncreaseItem = (menuItem) => {
dispatch(increaseItemCart({ id: menuItem.card.info.id }));
};
if (CartItem.length === 0) {
return (
<div className="empty">
<h1 className="text-black mt-10">Cart is empty</h1>
<p className="text-black mt-10">Add items</p>
</div>
);
}
return (
<div className=" ">
<div className="flex justify-center">
<h1 className="text-2xl font-bold uppercase text-black">CART</h1>
<button
className=" uppercase font-bold text-lg bg-orange-600 text-center rounded-lg p-2 text-white m-2
hover:text-orange-600 hover:bg-white hover:border-orange-500 border-1
"
onClick={() => {
dispatch(clearCart());
}}
>
CLEAR CART
</button>
</div>
<div className="outer grid grid-cols-2 gap-4 h-[70vh] w-[70vw] mx-auto">
<div className="menu-item overflow-x-scroll ">
{Array.isArray(CartItem) &&
CartItem.map((menuItem) => (
<div
className="flex gap-10 justify-start mb-4"
key={menuItem.card && menuItem.card.info.id}
>
<div className="image inline-block ">
<img
className="w-[164px] h-[164px] object-cover block rounded-md aspect-square"
src={CARD_IMG + menuItem.card.info.imageId}
/>
</div>
<div className=" w-[80%] ">
<span className="text-lg font-semibold">
{menuItem.card.info.name}
</span>
<p className="line-clamp-1">
{menuItem.card.info.description}
</p>
<p className="font-bold mt-1 text-black inline-block opacity-70">
{price.toFixed(2) * menuItem.count}
</p>
<p>
{" "}
₹{" "}
{(menuItem.card.info.price.toFixed(2) / 100 ||
menuItem.card.info.defaultPrice.toFixed(2) / 100) *
menuItem.count}
</p>
<p className=" inline-block ml-2">
(
{
(fixedPrice =
menuItem.card.info.price.toFixed(2) / 100 ||
menuItem.card.info.defaultPrice.toFixed(2) / 100)
}
{"X"} {menuItem.count})
</p>
<div className="buttons flex justify-between mt-9 ">
<div className=" justify-start">
<button
disabled={menuItem.count <= 1}
className="bg-orange-500 disabled:bg-orange-500/50 disabled:cursor-not-allowed text-white font-bold w-8 h-8 rounded-md"
onClick={() => handleDecreaseItem(menuItem)}
>
-
</button>
<p className="font-bold inline-block text-black w-8 h-8 ml-6">
{menuItem.count}
</p>
<button
className="bg-orange-500 text-white font-bold w-8 h-8 rounded-md"
onClick={() => handleIncreaseItem(menuItem)}
>
+
</button>
</div>
<div className="">
<button
className="border ml-20 border-orange-500 text-xs font-bold text-white bg-orange-500 p-2 px-4 rounded-md
hover:text-orange-500 hover:bg-white hover:border-orange-500 "
onClick={() => {
dispatch(removeItem(menuItem));
}}
>
Remove
</button>
</div>
</div>
</div>
</div>
))}
</div>
<div className="order-page shadow-md md:m-0 p-4">
<h2 className="text-xl font-bold border-b pb-4 mb-6">
Order Summary
</h2>
<div className=" leading-10 font-bold">
<div className="price-item flex mb-6 justify-between">
<p className="text-gray-600">Price ( {CartItem.length} items)</p>
{/* <p className="font-bold text-lg">₹ {CartItem.items.toFixed(2)} </p> */}
<p className="font-bold text-lg">₹ {price.toFixed(2)} </p>
</div>
<div className="discount text-gray-600 flex mb-6 justify-between">
<p className="">Discount (10%) </p>
<p className="font-bold text-black text-lg">
{" "}
- ₹ {discountPrice.toFixed(2)}
</p>
</div>
<div className="delivery text-gray-600 flex mb-6 justify-between">
<p> Delivery charges (2%) </p>
<p className="font-bold text-black text-lg">
₹ {deliveryFees.toFixed(2)}
</p>
</div>
<div className="reward border-b">
<p className="mb-6 text-black">
{" "}
You'll save ₹{discountPrice.toFixed(2)} on this order 🎉{" "}
</p>
</div>
</div>
<div className="total-amt flex text-2xl font-bold mt-8 justify-between mb-4 ">
<p className=" "> Total Amount </p>
<p className="text-orange-500 ">₹{finalAmount.toFixed(2)}</p>
</div>
<div className="place-order ">
<button
className="w-full block border uppercase font-bold border-orange-500 text-lg
text-center p-4 rounded-md
hover:text-white text-orange-500 hover:bg-orange-600 bg-white "
>
Place order
</button>
</div>
</div>
</div>
</div>
);
};
export default Cart;
型
menuItems.js
import { useDispatch } from "react-redux";
import { CARD_IMG } from "../utils/constants";
import { addItem, removeItem } from "../store/cartSlice";
const RestaurantMenuItems = ({ items }) => {
const dispatch = useDispatch();
const handleAddItem = (menuItem) => {
console.log("add clicked");
try {
dispatch(addItem(menuItem));
} catch (error) {
console.error("Error in handleAddItem:", error);
}
};
return (
<div className="">
{items &&
items.map((menuItem) => (
<div
key={menuItem.card && menuItem.card.info.id}
className="p-2 m-2 border-b-2 border-gray-400 text-left flex justify-between"
>
<div className="w-1/2 ">
<div className="p-2">
<span className="font-bold">{menuItem.card.info.name}</span>
<p className="font-bold mt-1 text-black opacity-70">
₹{" "}
{menuItem.card.info.price
? menuItem.card.info.price / 100
: menuItem.card.info.defaultPrice / 100}{" "}
</p>
<p className="text-base mt-2 text-black opacity-70 w-80">
{menuItem.card.info.description}
</p>
</div>
</div>
<div className="container-ib p-4 w-3/12 relative">
<img
className="container-i w-full relative h-32 rounded-lg"
src={CARD_IMG + menuItem.card.info.imageId}
/>
<div className="container-btn">
<button
className="w-20 h-8 absolute bottom-1 ml-2 left-24 transform -translate-x-1/2 bg-green-500 text-white border-none cursor-pointer m-0 p-1rem outline-none rounded-md font-bold text-xs shadow-md transition duration-200 ease-out hover:shadow-lg hover:text-green-500 hover:bg-white"
onClick={() => handleAddItem(menuItem )}
>
ADD
</button>
</div>
</div>
</div>
))}
</div>
);
};
export default RestaurantMenuItems;
型
1条答案
按热度按时间wztqucjr1#
在IncreaseItemCart和DecreaseItemCart中,删除state.price = state.totalPrice和additem逻辑是全局更新state.price
字符串