添加购物车中所有商品的数量,而不仅仅是每个特定 ID 1 个数字

问题描述 投票:0回答:1

所以我已经启动并运行了我的购物车。总价反映了购物车中的所有商品,但唯一的问题是您无法知道总共有多少商品。如果我有一件商品,那没问题,因为购物车图标显示 1。但是,如果我将两件相同的商品放入购物车,尽管购物车中的总价反映了 2 件商品,它仍会显示 1。我怎样才能获得购物车号码来反映商品总数。我是使用 Context 的新手,所以也许我刚刚犯了一个明显的错误?谢谢!

这是我的添加、删除和内容的上下文代码。

import { createContext, useState } from "react";

export const CartContext = createContext();

export function CartProvider({children}) {

    const [ cartItems, setCartItems ] = useState([]);

    const addToCart = (item) => {
        const isItemInCart = cartItems.find((cartItem) => cartItem.id === item.id); // Check if the item is already in the cart

        if (isItemInCart) {
            setCartItems(
                cartItems.map((cartItem) => // if the item is already in the cart, increase the quantity of the item
                cartItem.id === item.id
                ? { ...cartItem, quantity: cartItem.quantity + 1 }
                : cartItem // otherwise, return the cart item
                )
            );
        } else {
            setCartItems([...cartItems, { ...item, quantity: 1}]); // if the item is not in the cart, add the item to the cart
        }
    };

    const removeFromCart = (item) => {
        const isItemInCart = cartItems.find((cartItem) => cartItem.id === item.id);

        if (isItemInCart.quantity === 1) {
            setCartItems(cartItems.filter((cartItem) => cartItem.id !== item.id)); // if the quantity of the item is 1, remove the item from the cart
        } else {
            setCartItems(
                cartItems.map((cartItem) =>
                  cartItem.id === item.id
                    ? { ...cartItem, quantity: cartItem.quantity - 1 } // if the quantity of the item is greater than 1, decrease the quantity of the item
                    : cartItem
                    )
            )
        }
    };

    const clearCart = () => {
        setCartItems([]); // set the cart items to an empty array
    };

    const getCartTotal = () => {
        return cartItems.reduce((total, item) => total + item.price * item.quantity, 0); // calculate the total price of the items in the cart
    };

    return (
        <CartContext.Provider value={{cartItems, addToCart, removeFromCart, clearCart, getCartTotal}}>
            {children}
        </CartContext.Provider>
    )

}


export default CartContext;

这是我将商品添加到购物车的页面。

import React, { useState, useEffect, useContext } from 'react';
import { Link, useParams } from 'react-router-dom';
import data from './data.json';
import { CartContext } from '../Context/CartContext'

export default function Foodinfo() {

    const { addToCart } = useContext(CartContext)
    const params = useParams();
    const [item, setItem] = useState(null);

  
    useEffect(() => {

        // Parse the id from the URL params to an integer type
        const idFromUrl = parseInt(params.id, 10);

        // Find the item in the data array that matches the id from the URL
        const foundItem = data.find((d) => d.id === idFromUrl);
      
        // Set the found item in the state
        setItem(foundItem);
    }, [params.id]);
  
    return (
        <div>
            {/* Check if item exists before trying to access its properties */}
            {item ? (
                <div className="flex flex-wrap border-4 border-red-500 rounded-[25px] bg-white mt-12 md:mt-24 mx-auto justify-center max-w-[80%] md:max-w-[50%]">
                    <h2 className="my-auto py-5 mx-auto md:text-2xl">{item.title}</h2>
                    <img src={item.pic} alt={item.name} className="w-[400px] h-[300px] mx-auto pb-5 md:mt-5" />
                  <div className="flex flex-col mx-auto">  
                    <h1 className="font-bold text-center md:my-auto md:text-2xl">Item Info</h1>
                    <p className="my-3 mx-auto text-center md:my-auto md:text-2xl">{item.info}</p>      
                    <p className="text-center mb-3 md:my-auto md:text-2xl md:pb-3"><strong>Calories:</strong> {item.calories}</p>            
                    <button onClick={() => addToCart(item)} className="mx-auto border-4 border-red-600 bg-red-300 rounded-xl mb-3 w-[150px] hover:bg-red-500 hover:scale-[105%] ease-in-out duration-75 font-semibold">Add To Cart</button>
                  </div>
                </div>
            ) : (
                <p>Loading...</p>
            )}
        </div>
    );
}

这是我的购物车页面。

import React, { useContext } from 'react'
import { CartContext } from '../Context/CartContext'
import { Link } from 'react-router-dom';

export default function Cart() {

  const { cartItems, removeFromCart, getCartTotal, clearCart } = useContext(CartContext);

  // Cart price and tax price
  const itemsPrice = {getCartTotal}
  const taxPrice = itemsPrice * 0.14;
  const totalPrice = itemsPrice + taxPrice

  return (
    <div>
      <div className="bg-white h-16 mb-7 flex items-center">
        <h1 className="text-2xl mx-auto font-semibold">Checkout Cart</h1>
      </div>
      <div className="flex justify-center mx-auto flex-col border-4 border-red-500 rounded-[25px] bg-white max-w-[500px]">
        {cartItems.map((item, index) => (
          <div key={index} className="border-2 border-red-500 rounded-[25px] mx-7 my-7">
            <img className="w-[400px] h-[300px] rounded-[25px] px-2 py-2 mx-auto" src={item.pic} alt={item.title} />
            <div className="text-center">
              <p>{item.title}</p>
              <p>{item.price}</p>
            </div>
            <div className="flex">
              <button onClick={() => removeFromCart(item)} className="font-semibold mx-auto border-2 text-center border-red-600 bg-red-300 rounded-xl mb-3 w-[150px] hover:bg-red-500 hover:scale-[105%] ease-in-out duration-75">Remove From Cart</button>
            </div>
          </div>
        ))}
        {
          cartItems.length > 0 ? (
            <div className="flex flex-col justify-between items-center">
          <h1 className="text-lg font-bold">Total: ${getCartTotal()}</h1>
          <button 
            onClick={() => alert('I wish you could!')}
            className="py-2 font-bold border-2 text-center border-red-600 bg-red-300 rounded-xl mb-3 w-[150px] hover:bg-red-500 hover:scale-[105%] ease-in-out duration-75">Checkout!</button>
          <button
            className="mt-10 px-4 border-2 text-center border-red-600 bg-red-300 rounded-xl mb-3 w-[120px] hover:bg-red-500 hover:scale-[105%] ease-in-out duration-75"
            onClick={() => {
              clearCart()
            }}
          >
            Clear cart
          </button>
        </div>
          ) : (
            <div className="flex flex-col mx-auto">
              <h1 className="text-lg font-bold text-center my-3">Your cart is empty</h1>
              <Link to="/">
                <button className="border-2 font-semibold text-center border-red-600 bg-red-300 rounded-xl mb-3 w-[150px] hover:bg-red-500 hover:scale-[105%] ease-in-out duration-75">Return to Menu</button>
              </Link>
            </div>
          )
        }
      </div>
    </div>
  )
}

最后这是我的导航栏,其中包含购物车图标和显示购物车商品数量的数字。

import React, {useState, useContext} from 'react'
import {AiOutlineClose, AiOutlineMenu} from 'react-icons/ai'
import { Link } from 'react-router-dom'
import { CartContext } from '../Context/CartContext'

const Navbar = () => {

    const { cartItems } = useContext(CartContext)
    const [nav, setNav] = useState(true)
    const [ showModal, setShowModal ] = useState(false);

    const toggle = () => {
        setShowModal(!showModal)
    }

    const handleNav = () => {
        setNav(!nav)
    }

  return (
    <nav className="h-20 mx-auto p-4 font-bold bg-red-200">
        <div className="menubar">
            {!nav ? <AiOutlineClose size={20} className="text-white" /> : <AiOutlineMenu onClick={handleNav} size={20} color="red" className="hover:cursor-pointer" />}
            <h1 className="text-3xl font-bold m-auto">Brian's Burger Bash</h1>
            <div className="flex">
              <Link to="/cart"><img src="/bag.jpg" className="bag relative" /></Link>
              {!showModal && <button className='absolute bg-[#FF0000] rounded-full text-white w-6 right-2 bottom-4'
                  onClick={toggle}
              >{cartItems.length}</button>}
            </div>
        </div>
        <div className={!nav ? "fixed left-0 top-0 w-[435px] bg-red-600 text-white h-full border-r border-r-gray-90 ease-in-out duration-200" : "ease-in-out duration-200 fixed left-[-100%]"}>
          <div className="flex">
            <h1 className="w-full text-3xl font-bold text-black-500 m-3 mt-4 ml-14">BBB's</h1>
            <button onClick={handleNav} className="mr-14 mt-4">X</button>
          </div>
          <ul className="uppercase p-7 text-center text-2xl">
            <Link to='/'><li onClick={handleNav} className="p-7 hover:underline decoration-solid decoration-black decoration-4">MENU</li></Link>
            <Link to='locations'><li onClick={handleNav} className="p-7 hover:underline decoration-solid decoration-black decoration-4">LOCATIONS</li></Link>
            <Link to='contact'><li onClick={handleNav} className="p-7 hover:underline decoration-solid decoration-black decoration-4">CONTACT US</li></Link>
            <Link to='careers'><li onClick={handleNav} className="p-7 hover:underline decoration-solid decoration-black decoration-4">CAREERS</li></Link>
          </ul>
        </div>
    </nav>
  )
}

export default Navbar
javascript reactjs react-hooks react-context shopping-cart
1个回答
0
投票
let totalCartItems = 0;

cartItems.forEach((item)=>{ 
  totalCartItems = totalCartItems + item.quantity;
})

您需要检查购物车中所有商品的数量并将其添加到 获取购物车总商品数。

© www.soinside.com 2019 - 2024. All rights reserved.