所以我已经启动并运行了我的购物车。总价反映了购物车中的所有商品,但唯一的问题是您无法知道总共有多少商品。如果我有一件商品,那没问题,因为购物车图标显示 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
let totalCartItems = 0;
cartItems.forEach((item)=>{
totalCartItems = totalCartItems + item.quantity;
})
您需要检查购物车中所有商品的数量并将其添加到 获取购物车总商品数。