电子商务 MERN 项目中计算购物车总数的问题

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

我首先要提到的是,我是编程新手,如果我提出的问题可能太基本或解决方案很明显,请提前抱歉。 这也是我在 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;
javascript reactjs shopping-cart
1个回答
0
投票

您面临的问题似乎与您在 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 调用获取的数据还是从上下文中获取的数据。

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