redux 我如何阻止价格覆盖购物车中的新价格?

but5z9lq  于 9个月前  发布在  其他
关注(0)|答案(1)|浏览(118)

我已经创建了一个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;

wztqucjr

wztqucjr1#

在IncreaseItemCart和DecreaseItemCart中,删除state.price = state.totalPrice和additem逻辑是全局更新state.price

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 });
    }

    // Calculate price for the added item only
    const addedItem = state.items[existingItemIndex] || state.items[state.items.length - 1];
    const itemPrice = addedItem.card.info.price / 100 || addedItem.card.info.defaultPrice / 100;
  
    state.totalPrice += itemPrice;
    state.discountPrice = (state.totalPrice * 10) / 100;
    state.deliveryFees = (state.totalPrice * 5) / 100;
  },

  // ... other reducers

  decreaseItemCart: (state, action) => {
    const { id } = action.payload;
    const itemToDecrease = state.items.find(
      (item) => item.card.info.id === id
    );

    if (itemToDecrease && itemToDecrease.count > 1) {
      itemToDecrease.count -= 1;

      // Calculate price for the decreased item only
      const itemPrice = itemToDecrease.card.info.price / 100 || itemToDecrease.card.info.defaultPrice / 100;
      state.totalPrice -= itemPrice;
      state.discountPrice = (state.totalPrice * 10) / 100;
      state.deliveryFees = (state.totalPrice * 5) / 100;
    }
  },

  increaseItemCart: (state, action) => {
    const { id } = action.payload;
    const itemToIncrease = state.items.find(
      (item) => item.card.info.id === id
    );

    if (itemToIncrease) {
      itemToIncrease.count += 1;

      // Calculate price for the increased item only
      const itemPrice = itemToIncrease.card.info.price / 100 || itemToIncrease.card.info.defaultPrice / 100;
      state.totalPrice += itemPrice;
      state.discountPrice = (state.totalPrice * 10) / 100;
      state.deliveryFees = (state.totalPrice * 5) / 100;
    }
  },

  // ... other reducers  

}

字符串

相关问题