总计在购物车中显示 NaN
Total is displaying NaN in Cart
所以我目前面临的问题是这样的。我在 CartContext 中有一个购物车逻辑。除了结账组件中的总价外,一切正常,它应该对购物车中所有商品的价格求和,但显示的是 NAN。这是 CodeSandbox 的 link 以便更好地理解 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
您正在处理错误数据。在这种情况下,正确的响应是向负责后端的任何人请求经过清理的数据。如果后台的负责人还是你,你应该在后台解决这个问题,而不是在前端。
长话短说,不要使用 parseFloat()
。当您必须将字符串转换为数字时,更安全的做法是使用 Number(val)
(或其 shorthand:+val
)。 (不过,这仍然是一个赌注...)
另一件小事:您正在使用 amount: 0
将商品添加到购物车。不应该是1
吗?
setCart(
cart.concat({
amount: 1,
price: +book.RegularPrice,
...book
})
);
最后一点:如果 book
已经设置了任何这些属性,那么您现在拥有的内容将覆盖您对 amount
和 price
的分配。如果你想对分配有完全的控制权(和信心),你应该先传播对象,然后分配:
setCart(
cart.concat({
...book,
amount: 1,
price: +book.RegularPrice
})
);
看到了here.
所以我目前面临的问题是这样的。我在 CartContext 中有一个购物车逻辑。除了结账组件中的总价外,一切正常,它应该对购物车中所有商品的价格求和,但显示的是 NAN。这是 CodeSandbox 的 link 以便更好地理解 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
您正在处理错误数据。在这种情况下,正确的响应是向负责后端的任何人请求经过清理的数据。如果后台的负责人还是你,你应该在后台解决这个问题,而不是在前端。
长话短说,不要使用 parseFloat()
。当您必须将字符串转换为数字时,更安全的做法是使用 Number(val)
(或其 shorthand:+val
)。 (不过,这仍然是一个赌注...)
另一件小事:您正在使用 amount: 0
将商品添加到购物车。不应该是1
吗?
setCart(
cart.concat({
amount: 1,
price: +book.RegularPrice,
...book
})
);
最后一点:如果 book
已经设置了任何这些属性,那么您现在拥有的内容将覆盖您对 amount
和 price
的分配。如果你想对分配有完全的控制权(和信心),你应该先传播对象,然后分配:
setCart(
cart.concat({
...book,
amount: 1,
price: +book.RegularPrice
})
);
看到了here.