我首先要提到的是,我是编程新手,如果我提出的问题可能太基本或解决方案很明显,请提前抱歉。 这也是我在 StackOverflow 上提出的第一个问题,如果我错过提供任何重要的细节,请提前抱歉。 我正在开发一个电子商务网络应用程序用于学习目的,以便更好地掌握 javascript 和反应。 这也是第一次尝试设置购物车,我无法计算出购物车的总计。我收到错误:“无法读取未定义的属性(读取‘价格’)”。 据我评估,我无法正确访问计算所需的商品价格,并且无论我如何尝试,我都无法解决它。
这是我的 CartProduct 的代码,我可以在其中获取包括价格在内的产品详细信息:
import Button from "react-bootstrap/Button";
import React, { useState, useEffect } from "react";
import { useCart } from "../context/cart.context";
import { useParams } from "react-router-dom";
import axios from "axios";
const API_URL = "http://localhost:4000";
function CartProduct({ id, quantity}) {
const { getProductQuantity, removeFromCart } = useCart();
const [productData, setProductData] = useState();
const [updatedQuantity, setUpdatedQuantity] = useState(quantity);
useEffect(() => {
if (!productData) {
axios
.get(`${API_URL}/api/products/${id}`)
.then((response) => {
console.log("this is the cart product response data",response.data);
setProductData(response.data);
})
.catch((error) => {
console.error("Error fetching product details:", error);
});
}
}, [id, productData, quantity]);
if (!productData) {
// Data is still being loaded
return <p>Loading...</p>;
}
const quantityInCart = getProductQuantity(id);
const handleRemoveFromCart = () => {
removeFromCart(id);
};
const handleQuantityChange = (e) => {
// Ensure the quantity is a positive integer
const newQuantity = parseInt(e.target.value, 10);
if (!isNaN(newQuantity) && newQuantity >= 0) {
setUpdatedQuantity(newQuantity);
}
};
const newTotalPrice = (updatedQuantity * productData.price).toFixed(2);
return (
<>
<div className="cart-product">
<img src={productData.imageUrl} width={60}/>
<p className="flex-item">{productData.name}</p>
<p className="flex-item">
Quantity:
<input
type="number"
value={updatedQuantity}
onChange={handleQuantityChange}
min="1"
className="quantity-input"
/>
</p>
<p className="flex-item">Subtotal: {newTotalPrice} €</p>
<Button size="sm" onClick={handleRemoveFromCart}>
Remove
</Button>
</div>
<hr></hr>
</>
);
}
export default CartProduct;
这是我的 CartPage 代码,其中包含计算购物车总计的函数:
import React, { useState, useEffect, useContext } from "react";
import { Link } from "react-router-dom";
import { Button, Table } from "react-bootstrap";
import { CartContext } from "../context/cart.context";
import CartProduct from "../components/CartProduct";
function CartPage() {
const cart = useContext(CartContext);
const [productsCount, setProductsCount] = useState(0);
const cartProducts = cart.cartProducts;
const calculateCartTotal = (cartProducts) => {
let cartTotal = cartProducts.reduce((acc, curr) => {
return acc + curr.productData.price * curr.quantity;
}, 0);
return cartTotal;
};
useEffect(() => {
// Update products count when the cart changes
setProductsCount(cart.cartProducts.length);
// Calculate total cost when the cart changes
}, [cart.cartProducts]);
return (
<>
<div className="cart-page">
<h2>Cart</h2>
{!cart.cartProducts.length && (
<div className="empty-cart">
<h4>Your cart is empty.</h4>
<Link to="/products">
<div
style={{
display: "flex",
justifyContent: "center",
alignItems: "center",
}}
>
<Button>Shop now</Button>
</div>
</Link>
</div>
)}
{cart.cartProducts.length > 0 && (
<div>
<Link to="/products">
<Button className="button-cart">Continue Shopping</Button>
</Link>
{cart.cartProducts.map((currentProduct, idx) => (
<CartProduct
key={idx}
id={currentProduct.id}
quantity={currentProduct.quantity}
productData={currentProduct.productData}
></CartProduct>
))}
<h3>Total: € {calculateCartTotal(cart.cartProducts)}</h3>
<div
style={{
display: "flex",
justifyContent: "center",
alignItems: "center",
}}
>
<Button className="cart-button">Proceed to Checkout</Button>
</div>
</div>
)}
</div>
</>
);
}
export default CartPage;
您面临的问题似乎与您在 CartProduct 组件和 CartPage 之间传递和处理 ProductData 的方式有关。 ProductData 在某些时候似乎未定义,导致尝试访问其属性时出现错误。
在 CartProduct 组件中,您使用 Axios 调用异步获取 ProductData。但是,组件的呈现不会等待此数据可用,从而导致在设置之前访问诸如productData.price之类的属性时出现潜在问题。
为了解决这个问题,您应该添加一个检查,以确保在根据产品数据及其必要的属性(如价格)执行计算之前可用。
在您的 CartProduct 组件中,修改 newTotalPrice 的计算:
const newTotalPrice = productData && productData.price
? (updatedQuantity * productData.price).toFixed(2)
: "Loading...";
通过在计算 newTotalPrice 之前检查 ProductData 是否可用,您将避免尝试计算不完整或未定义的数据。如果productData尚不可用,您可以显示加载消息或根据您的UI要求进行处理。这应该有助于防止与访问未定义对象的属性相关的错误。
另一件事需要指出的是,您没有在 CartProduct 中使用 ProductData 属性。您应该决定是要使用从 api 调用获取的数据还是从上下文中获取的数据。