UseState React hook:更新状态不一致

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

我正在尝试构建一个购物车。大约一个小时前,我创建了另一篇帖子,其中包含我遇到的类似问题,该问题已解决,我能够正确实施该问题。

在此购物车中,我将在页面的一侧显示购物车中的所有商品,并在另一侧显示订单详细信息/定价。这是我所拥有的视觉效果:

Image of shopping cart, currently.

如图所示,对于每个项目,我应该能够更新数量(使用下拉列表)并在必要时删除该项目(每个项目上的 X 标志)。我的最后一个问题是关于一个问题,当我更新某个商品的下拉菜单(数量)时,该特定商品的价格值不会更新。看来我没有正确更新状态,而且我已经解决了这个问题。

我现在遇到的问题是,当我更新其中一件商品的数量时,订单摘要也应该更新。我使用相同的项目 (

cart
) 来计算两者的值。

需要注意的是,我仅在尝试更新商品数量时才会遇到此问题。当我删除一个项目时,订单摘要会相应更改。只是当我尝试更改数量时它不起作用。

这是包含列表和订单夏天的组件的代码(标题为

OuterCart
):

import React, { useState } from 'react';
import CartItem from './CartItem';
import CartOrder from './CartOrder';

const OuterCart = () => {
  const items = [
    {
      name: 'Boardwalk view',
      quantity: 3,
      finish: 'Non-matted',
      size: '4x8',
      price: 19.99,
      id: 0,
    },
    {
      name: '2 Boardwalk view',
      quantity: 1,
      finish: 'Matted',
      size: '3x6',
      price: 20.99,
      id: 1,
    },
    ... // there are more items
  ]
  
  const [cart, setCart] = useState(items);

  function removeItem(id) { // function run when I click the X
    const newCart = cart.filter((item) => item.id !== id)
    setCart(newCart);
  }

  function changeQuantity(event, id) { // function run when I update the dropdown on an item
    let newCart = [...cart];
    for (let i=0; i<cart.length; i++) {
      if (cart[i].id === id) {
        newCart[i] = {
          ...newCart[i],
          quantity: parseInt(event.target.value),
        }
      }
    }
    setCart(newCart);
  }

  return (
    <div className='px-3 text-gray-800'>
      <h1 className='my-10 text-2xl font-bold'>Shopping Cart</h1>
      <div className='grid grid-cols-10'>
        <div className='col-span-5 flex flex-col mb-5 border-b text-gray-800'>
          {cart.length === 0 ? <p>You have no items in your cart. <a href="/shop" className='text-indigo-600'>Go shopping</a> to add some!</p> : ""}
          {cart.map((value, index, array) => {
            return(<CartItem value={value} removeItem={removeItem} changeQuantity={changeQuantity} />)
          })} // this works just fine for each item, no matter the action
        </div>
        <div className='col-span-1'></div>
        <CartOrder cart={cart} /> // this is the order summary, only updates appropriately when I remove an item, not when I change the quantity
      </div>
    </div>
  );
};

export default OuterCart;

如有必要,这里是订单摘要组件的代码:

import { React } from 'react';

const CartOrder = ({cart}) => {
  const subtotal = cart.reduce((sum, item) => sum + item.price, 0);

  const taxEstimate = parseFloat((subtotal * .06).toFixed(2));
  const taxEstimateString = parseFloat(subtotal * .06).toFixed(2);

  const orderTotalString = parseFloat(subtotal + taxEstimate).toFixed(2);
  const orderTotal = parseFloat((subtotal + taxEstimate).toFixed(2));

  return (
    <div className='col-span-4 text-gray-800'>
      <div className='rounded-xl bg-gray-100 px-7 py-10'>
        <h1 className='text-lg font-medium mb-4'>Order summary</h1>

        <div className='flex justify-between border-b py-4'>
          <p className='text-gray-500 text-sm'>Subtotal</p>
          <p className='font-medium text-sm'>${subtotal}</p>
        </div>
        <div className='flex justify-between border-b py-4'>
          <p className='text-gray-500 text-sm'>Tax estimate</p>
          <p className='font-medium text-sm'>${taxEstimateString}</p>
        </div>
        <div className='flex justify-between py-4'>
          <p className='font-semibold'>Order total</p>
          <p className='font-semibold'>${orderTotalString}</p>
        </div>
        
        <a href='/' className='mt-5 inline-block w-full bg-indigo-600 hover:bg-indigo-700 transition text-gray-50 text-center px-3 py-3 font-medium tracking-wide rounded-lg'>Checkout</a>
      </div>
    </div>
  );
};

export default CartOrder;

我讨厌这么快地连续问两个相关的问题,但我已经在这个问题上停留了一个小时了。如有任何帮助,我们将不胜感激。

javascript reactjs react-hooks cart
1个回答
1
投票

CartOrder
功能中,您没有考虑物品的数量。

应该是=>

  const subtotal = cart.reduce((sum, item) => sum + item.price*item.quantity, 0);
© www.soinside.com 2019 - 2024. All rights reserved.