代码之家  ›  专栏  ›  技术社区  ›  Jason Roman

我的函数将在状态更新后循环通过旧状态

  •  0
  • Jason Roman  · 技术社区  · 2 年前

    用户添加一个3.00美元的项目,总价格高达0.00美元

    用户添加两个3.00美元的项目,总价格达到6.00美元

    我似乎不明白为什么它会这样。

    免责声明不会部署此项目。这个项目是为了利用我已经掌握的技能而创建的。

    import React from 'react'
    
    import StoreSelection from './StoreSelection';
    
    
    const Store = ({inventory,cart,setCart,setPrice}) => {
      const cart_addItem = (newItem) =>{
    
        let duplicate = false;
        let indextochange = 0;
    
        for(let item in cart){
          if(cart[item].id === newItem.id){
            duplicate = true;
            indextochange = item;
          }
        }
        
        if(duplicate===true){
          let newList = [];
          for(let item in cart){
            newList[item] = cart[item];
          }
          newList[indextochange].quantity +=1;
          setCart(newList);
        }else{
          newItem.quantity = 1;
          setCart([...cart,newItem]);
        }
        calculatePrice(cart);
      }
    
      const calculatePrice = (list) =>{
        let newprice = 0;
        console.log(list);
        for(let item in list){
          console.log(list[item].quantity);
          newprice = (parseFloat(list[item].price) * list[item].quantity) + newprice;
        }
        setPrice(newprice);
      }
      
      return (
        <div>
          <StoreSelection inventory={inventory} cart_addItem={cart_addItem}/>
        </div>
      )
    }
    
    export default Store
    
    1 回复  |  直到 2 年前
        1
  •  0
  •   jsejcksn    2 年前

    所用挂钩的参考文件:

    import {default as React, useCallback, useEffect} from 'react';
    import StoreSelection from './StoreSelection';
    
    // This doesn't need to be created in your component.
    // Creating it once, outside the component, is an optimization:
    function calculatePrice (cart) {
      let updatedPrice = 0;
      // console.log(list);
      for (const item of cart){
        // console.log(item.quantity);
        updatedPrice += parseFloat(item.price) * item.quantity;
      }
      return updatedPrice;
    }
    
    export default function Store ({cart, inventory, setCart, setPrice}) {
      // You can calculate the new price every time the cart changes by updating it
      // in response to changes in the cart state:
      useEffect(() => setPrice(calculatePrice(cart)), [cart]);
      // However, if you don't manually update the price state in other places,
      // then it doesn't need to be state at all. You can just create it this way
      // in the parent component where it was defined:
      // const price = useMemo(() => calculatePrice(cart), [cart]);
    
      const cart_addItem = useCallback(item => {
        // In your question's code it appears as though it is not certain that
        // the added item's `quantity` property is set. If that's not the case,
        // then you can simply delete the following statement. If it is
        // `undefined` or `null`, then this will set it to `1`:
        item.quantity ??= 1;
    
        // Use the functional form of the argument to `setCart`. This way,
        // it will not depend on an external state value (so it will
        // always be current and also won't be needed in the dependency array):
        setCart(cart => {
          const index = cart.findIndex(currentItem => currentItem.id === item.id);
          const updatedCart = [...cart];
          if (index >= 0) {
            // Be sure not to mutate the item object within in the cart state:
            const updatedItem = {...updatedCart[index]};
            updatedItem.quantity += item.quantity;
            updatedCart[index] = updatedItem;
          }
          else updatedCart.push(item);
          return updatedCart;
        });
      }, [setCart]);
      
      return (
        <div>
          <StoreSelection {...{cart_addItem, inventory}}/>
        </div>
      );
    }