【问题标题】:Total is displaying NaN in CartTotal 在购物车中显示 NaN
【发布时间】:2021-04-06 19:08:26
【问题描述】:

所以我目前面临的问题是这个。我在 CartContext 中有一个购物车逻辑。一切正常,除了位于结帐组件中的总数,它应该汇总购物车中物品的所有价格,而是显示 NAN。这是 CodeSandbox 的链接,以便更好地理解 https://codesandbox.io/s/frosty-sound-5y7pg?file=/src/CartItem.js:1486-1494.Please 如果沙盒有问题,请发表评论

购物车上下文

import React from "react";
function getCartFromLocalStorage() {
  return localStorage.getItem("cart")
    ? JSON.parse(localStorage.getItem("cart"))
    : [];
}

const CartContext = React.createContext();

function CartProvider({ children }) {
  const [cart, setCart] = React.useState(getCartFromLocalStorage());
  const [total, setTotal] = React.useState(0);
  const [cartItems, setCartItems] = React.useState(0);

  React.useEffect(() => {
    localStorage.setItem("cart", JSON.stringify(cart));

    let newTotal = cart.reduce((total, cartItem) => {
      return (total += cartItem.amount * cartItem.price);
    }, 0);
    newTotal = parseFloat(newTotal.toFixed(2));
    setTotal(newTotal);
    // cart items
    let newCartItems = cart.reduce((total, cartItem) => {
      return (total += cartItem.amount);
    }, 0);
    setCartItems(newCartItems);
  }, [cart]);

  // global functions
  const removeItem = id => {
    setCart([...cart].filter(item => item.id !== id));
  };
  const increaseAmount = id => {
    const newCart = [...cart].map(item => {
      return item.id === id
        ? { ...item, amount: item.amount + 1 }
        : { ...item };
    });
    setCart(newCart);
  };
  const decreaseAmount = (id, amount) => {
    if (amount === 1) {
      removeItem(id);
      return;
    } else {
      const newCart = [...cart].map(item => {
        return item.id === id
          ? { ...item, amount: item.amount - 1 }
          : { ...item };
      });

      setCart(newCart);
    }
  };
  const addToCart = book => {
    const { id, image, by, bookName,RegularPrice } = book;
    const item = [...cart].find(item => item.id === id);

    if (item) {
      increaseAmount(id);
      return;
    } else {
      const newItem = { id, image, by, bookName, RegularPrice, amount: 1 };
      const newCart = [...cart, newItem];
      setCart(newCart);
    }
  };
  const clearCart = () => {
    setCart([]);
  };
  return (
    <CartContext.Provider
      value={{
        cart,
        cartItems,
        total,
        removeItem,
        increaseAmount,
        decreaseAmount,
        addToCart,
        clearCart
      }}
    >
      {children}
    </CartContext.Provider>
  );
}

export { CartContext, CartProvider };

购物车物品

import React, { useContext } from "react";
import {Link, useHistory } from 'react-router-dom'
import { CartContext } from "../../context/cart";
import { FaAngleDown, FaAngleUp } from "react-icons/fa";
import Checkout from "./Checkout";
export default function CartItem({ id, image,bookName, RegularPrice, by, amount }) {
  const { removeItem, increaseAmount, decreaseAmount } = React.useContext(
    CartContext
  );
  return (
      <div id={id} className="cart__item">
          <img className='cart__image' src={image}  />
        <div className='cart__itemdesc'>
         <h4>{bookName}</h4>
        <h6 className='cart__by'>By: {by}</h6>
        <button
          className="cart__removebtn"
          onClick={() => {
            removeItem(id);
          }}
         >
          Remove
        </button>
        <div>
        <button
          className="cart-btn amount-btn"
          onClick={() => {
            increaseAmount(id);
          }}
        >
          <FaAngleUp />
        </button>
        <p className="item-amount">{amount}</p>
        <button
          className="cart-btn amount-btn"
          onClick={() => {
            decreaseAmount(id, amount);
          }}
        >
          <FaAngleDown />
        </button>
      </div>
        </div>  
        <span className='circle'><span className='circleone'></span></span>
        <span className='cart__regular'>{RegularPrice}</span>      
        <div>   
        <Checkout />
        </div>    
    </div>
  );
}

结帐

import React,{useContext} from 'react'
import { CartContext } from '../../context/cart'
import {Link, useHistory } from 'react-router-dom'
import EmptyCart from './EmptyCart';

const Checkout = () => {
  const history = useHistory()
  const {cart, total} = useContext(CartContext)
  if (cart.length === 0) {
    return <EmptyCart />;
  }

    return (
        <div className='checkout'>
            <h2>Summary</h2>
            <h2>Subtotal : ${total}</h2>
            <Link to='/stripecontainer' className='checkout__btnOne'>Proceed to Checkout</Link>            
        </div>
    )
}

export default Checkout

【问题讨论】:

  • 这能回答你的问题吗? Cart total is showing NAN instead of Total price
  • 似乎可以在沙盒中工作?
  • 请不要再发同样的问题overover。如果您有新信息,请编辑原始问题。
  • 我不知道它在你的沙箱中是如何工作的,而我的沙箱中显示的是 NaN
  • 我的沙箱工作正常,但我必须在一个项目上单击两次才能计为金额 1。

标签: javascript json reactjs commerce


【解决方案1】:

您正在处理不良数据。在这种情况下,正确的响应是向负责后端的任何人请求经过清理的数据。如果后端的负责人还是你,你应该在后端解决这个问题,而不是在前端。

长话短说,不要使用parseFloat()。当您必须将字符串转换为数字时,更安全的选择是使用Number(val)(或其简写:+val)。 (不过,这仍然是一个赌注……)

另一件小事:您正在使用amount: 0 将商品添加到购物车。不应该是1吗?

setCart(
  cart.concat({
    amount: 1,
    price: +book.RegularPrice,
    ...book
  })
);

最后一点:如果book 已经设置了这些属性中的任何一个,那么您现在拥有的内容将覆盖您对amountprice 的分配。如果你想对分配有完全的控制(和信心),你应该先传播对象,然后分配:

setCart(
  cart.concat({
    ...book,
    amount: 1,
    price: +book.RegularPrice
  })
);

here

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-03-22
    • 1970-01-01
    • 2019-12-31
    • 1970-01-01
    相关资源
    最近更新 更多