首页 > 解决方案 > 为什么小计不能相互加起来?

问题描述

import React, { useEffect } from "react";
import { addToCart, removeFromCart } from "../actions/cartActions";
import { useDispatch, useSelector } from "react-redux";
import { Link } from "react-router-dom";
function CartScreen(props) {
  const cart = useSelector((state) => state.cart);

  const { cartItems } = cart;

  const productId = props.match.params.id;
  const qty = props.location.search
    ? Number(props.location.search.split("=")[1])
    : 1;
  const dispatch = useDispatch();
  const removeFromCartHandler = (productId) => {
    dispatch(removeFromCart(productId));
  };
  useEffect(() => {
    if (productId) {
      dispatch(addToCart(productId, qty));
    }
  }, []);

  const checkoutHandler = () => {
    props.history.push("/signin?redirect=shipping");
  };

  return (
    <div className="cart">
      <div className="cart-list">
        <ul className="cart-list-container">
          <li>
            <h3>Shopping Cart</h3>
            <div>Price</div>
          </li>
          {cartItems.length === 0 ? (
            <div>Cart is empty</div>
          ) : (
            cartItems.map((item) => (
              <li>
                <div className="cart-image">
                  <img src={item.image} alt="product" />
                </div>
                <div className="cart-name">
                  <div>
                    <Link to={"/product/" + item.product}>{item.name}</Link>
                  </div>
                  <div>
                    Qty:
                    <select
                      value={item.qty}
                      onChange={(e) =>
                        dispatch(addToCart(item.product, e.target.value))
                      }
                    >
                      {[...Array(item.countInStock).keys()].map((x) => (
                        <option key={x + 1} value={x + 1}>
                          {x + 1}
                        </option>
                      ))}
                    </select>
                    <button
                      type="button"
                      className="button"
                      onClick={() => removeFromCartHandler(item.product)}
                    >
                      Delete
                    </button>
                  </div>
                </div>
                <div className="cart-price">${item.price}</div>
              </li>
            ))
          )}
        </ul>
      </div>
      <div className="cart-action">
        <h3>
          Subtotal ( {cartItems.reduce((a, c) => a + c.qty, 0)} items) : ${" "}
          {cartItems.reduce((a, c) => a + c.price * c.qty, 0)}
        </h3>
        <button
          onClick={checkoutHandler}
          className="button primary full-width"
          disabled={cartItems.length === 0}
        >
          Proceed to Checkout
        </button>
      </div>
    </div>
  );
}

export default CartScreen;

此代码的主要目的是通过购物车屏幕的名称显示网页。购物车屏幕内是我想从另一个页面购买的所有商品,该页面取自另一个 js 文件,该文件包含这些产品的所有日期。

我想在这里突出显示这个特定的代码。

<h3>
Subtotal ( {cartItems.reduce((a, c) => a + c.qty, 0)} items) : ${" "}
{cartItems.reduce((a, c) => a + c.price * c.qty, 0)}
</h3>

这段代码的工作方式是:小计计算我在购物车中总共有多少物品,然后将每个产品的成本乘以它们的数量,然后再添加所有内容,并在我想要购买之前告诉我我想要购买的所有物品的成本买它。总价部分完全正常。

令我困惑的是,购物车中有多少物品的小计似乎并没有按照我的预期工作。

如果我在购物车中只有 2 件单独的物品我想购买其中的 1 件,其中小计告诉我我在购物车中总共有 2 件物品是正确的,那么它工作正常。但是,一旦我想从一件商品中购买 2 件,小计就会以某种方式从之前的 2 件声明变为 12 或者更确切地说是 1 代表一件商品,而 2 代表我想购买 2 件的另一件商品。出于某种原因,当它们应该显示 3 而不是 12 时,它们没有合并。

标签: javascriptreactjsreact-redux

解决方案


确保您的qtyprice属性不是字符串而是数字。如果您将这些值存储为数字,您的.reduce()方法将按预期工作:

const cartItems = [
  { qty: 1, price: 5.99 },
  { qty: 2, price: 25.0 },
  { qty: 5, price: 10.0 },
];

cartItems.reduce((a, c) => a + c.qty, 0); 
// => 8

cartItems.reduce((a, c) => a + c.price * c.qty, 0);
// => 105.99

如果您将+运算符与数字一起使用,它会按您的预期对它们进行求和。但是,如果您将数字存储为字符串并尝试计算它们的总和,它实际上会将它们连接成一个新字符串。

如果您使用*运算符,您会隐式地将字符串转换为数字,这就是总价格有效的原因,但项目总数无效:

const cartItems = [
  { qty: '1', price: '5.99' },
  { qty: '2', price: '25.00' },
  { qty: '5', price: '10.00' },
];

cartItems.reduce((a, c) => a + c.qty, 0);
// => "0125"

cartItems2.reduce((a, c) => a + c.price * c.qty, 0);
// => 105.99

要解决此问题,您需要确保将qtyprice作为数字存储或将它们转换为.reduce().

const cartItems = [
  { qty: '1', price: '5.99' },
  { qty: '2', price: '25.00' },
  { qty: '5', price: '10.00' },
];

cartItems.reduce((a, c) => a + Number(c.qty), 0);
// => 8

推荐阅读