代码之家  ›  专栏  ›  技术社区  ›  IPSDSILVA

UseState React钩子:更新状态不一致

  •  0
  • IPSDSILVA  · 技术社区  · 7 月前

    我在试着做一个购物车。就在大约一个小时前,我创建了另一个帖子,上面有一个我遇到的类似问题,这个问题得到了解决,我能够正确地实现它。

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

    Image of shopping cart, currently.

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

    我现在遇到的问题是,当我更新其中一个项目的数量时,订单摘要也应该更新。我正在使用同一个项目( 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;
    

    我不想这么快就连续问两个相关的问题,但我已经在这个问题上纠结了一个小时了。任何帮助都将不胜感激。

    1 回复  |  直到 7 月前
        1
  •  1
  •   Akshay    7 月前

    In CartOrder 功能,你们并没有考虑到物品的数量。

    它应该是=>

      const subtotal = cart.reduce((sum, item) => sum + item.price*item.quantity, 0);