【问题标题】:updating state -> object -> array -> object更新状态 -> 对象 -> 数组 -> 对象
【发布时间】:2020-07-01 01:25:24
【问题描述】:

迷失在深度嵌套的 setState 函数中。

我想要做的是将一个对象添加到我的组件状态中的对象内的数组中。我已经成功地这样做了,但我正在努力做到这一点,如果该对象已经存在,该函数将更新数量。我不确定我做错了什么。

状态

this.state = {
    products : [
        {
            productId: 1,
            productImage: 'tee1',
            productName: 'The Road Is Home Tee',
            productPrice: 25
        },
        {
            productId: 2,
            productImage: 'shorts1',
            productName: 'Striped Swim Shorts',
            productPrice: 50
        },
        {
            productId: 3,
            productImage: 'tee2',
            productName: 'Gray Long Sleeve',
            productPrice: 100
        },
        {
            productId: 4,
            productImage: 'hat1',
            productName: 'American Snapback',
            productPrice: 25
        },
        {
            productId: 5,
            productImage: 'shorts2',
            productName: 'American Shorts',
            productPrice: 50
        },
        {
            productId: 6,
            productImage: 'hat2',
            productName: 'Flex Fit Hat',
            productPrice: 100
        }
    ],
    cartData : {
        items: [],
        total: 0
    }
}

addToCart()

addToCart = (productId, size, quantity) => {
    for( let i=0; i < this.state.cartData.items.length; i++ ) {
        if (productId === this.state.cartData.items[i].productData.productId) {
            this.setState(prevState => {
                const items = prevState.cartData.items.map(item => {
                    if(i === (item.productId -1)) {
                        return item.productQuantity + quantity;
                    }
                })

                return {
                    items,
                }
            })
        } else {
            this.setState(prevState => ({
                cartData: {
                    ...prevState.cartData,
                    items: [...prevState.cartData.items, { productData: this.state.products[productId - 1], productSize: size, productQuantity: quantity }]
                }
            }))
        }
    }
}   

编辑 ***********

新代码更有条理,并且我在开始检查购物车是否为空之前实现了一个 IF 语句,然后再循环这些项目。还修复了一些小问题并添加了一些评论,但仍然没有得到我想要的结果

addToCart = (productId, size, quantity) => {
        // IF CART IS EMPTY (CANT USE FOR LOOP)
        if ( this.state.cartData.items.length === 0 ) {
            this.setState(prevState => ({
                cartData: {
                    ...prevState.cartData,
                    items: [...prevState.cartData.items, { productData: this.state.products[productId - 1], productSize: size, productQuantity: quantity }]
                }
            }))
        }
        // IF CART IS NOT EMPTY
        else {
            // LOOP THROUGH EACH ITEM
            for( let i=0; i < this.state.cartData.items.length; i++ ) {
                // IF PRODUCT EXISTS
                if (productId === this.state.cartData.items[i].productData.productId) {
                    // SET STATE (RETURNS A FUNCTION)
                    this.setState(prevState => {
                        // MAP THROUGH EACH ITEM
                        const items = prevState.cartData.items.map(item => {
                            // IF THE PRODUCT IDS MATCH
                            if(i === (item.productData.productId -1)) {
                                // RETURN AN OBJECT WITH SAME ITEM PROPERTIES
                                // ADJUST QUANTITY
                                return {
                                    ...item,
                                    productQuantity: item.productQuantity + quantity,
                                }
                            }
                            // RETURN UNAFFECTED ITEMS AS WELL
                            else {
                                return item
                            }


                        })

                        // RETURN OUR ITEMS TO SET STATE
                        return {
                            items,
                        }
                    })
                }
                // IF PRODUCT DOES NOT EXIST
                else {
                    this.setState(prevState => ({
                        cartData: {
                            ...prevState.cartData,
                            items: [...prevState.cartData.items, { productData: this.state.products[productId - 1], productSize: size, productQuantity: quantity }]
                        }
                    }))
                }
            }
        }
    }

现在我的应用程序将正确添加第一个产品。然后我开始遇到问题之后的任何事情。当我尝试添加具有相同产品 ID 的其他产品时,它不仅会增加它创建的整个其他对象的数量。

在这里迷路了,请帮忙!!!

附言 得到我在沙箱内使用 localhost 没有得到的错误,所以这里不是一个真正的选择

【问题讨论】:

    标签: javascript arrays reactjs object setstate


    【解决方案1】:

    我没有尝试运行代码(如果你提供了一个代码框或其他东西就可以了),但这应该会有所帮助。

    addToCart = (productId, size, quantity) => {
        for( let i=0; i < this.state.cartData.items.length; i++ ) {
            if (productId === this.state.cartData.items[i].productData.productId) {
                this.setState(prevState => {
                    const items = prevState.cartData.items.map(item => {
    
    
                        if(i === (item.productId -1)) {
                            // returns a copy of the known item with updated quantity
                            return {
                                ...item,
                                productQuantity: item.productQuantity + quantity,
                            };
                        } else {
                            return item // you need to return items that are not modified too
                        }
    
    
                    })
    
                    return {
                        items,
                    }
                })
            } else {
                this.setState(prevState => ({
                    cartData: {
                        ...prevState.cartData,
                        items: [...prevState.cartData.items, { productData: this.state.products[productId - 1], productSize: size, productQuantity: quantity }]
                    }
                }))
            }
        }
    }   
    

    【讨论】:

    • 对我来说很有意义,但我只是尝试过并且遇到与以前相同的问题。当我 console.log() 我的 cartData 它是空的......
    【解决方案2】:

    它有效。我希望它对你有帮助。 (对更有条理的代码进行了一些更改):

    const products = [
    {
      productId: 1,
      productImage: 'tee1',
      productName: 'The Road Is Home Tee',
      productPrice: 25
    },
    {
      productId: 2,
      productImage: 'shorts1',
      productName: 'Striped Swim Shorts',
      productPrice: 50
    },
    {
      productId: 3,
      productImage: 'tee2',
      productName: 'Gray Long Sleeve',
      productPrice: 100
    },
    {
      productId: 4,
      productImage: 'hat1',
      productName: 'American Snapback',
      productPrice: 25
    },
    {
      productId: 5,
      productImage: 'shorts2',
      productName: 'American Shorts',
      productPrice: 50
    },
    {
      productId: 6,
      productImage: 'hat2',
      productName: 'Flex Fit Hat',
      productPrice: 100
    }
    

    ]

    const [cart, setCart] = useState({
    items: [],
    total: 0
    })
    
    const isProductExist= productId =>
      cart.items.find(product => product.productId == productId)
    
    addToCart = (productId, size, quantity) => {
      if (isProductExist(productId)) {
      setCart(prevState => ({
        ...prevState,
        items: cart.items.map(item => {
          if (item.productId == productId) item.productQuantity += quantity
          item.productQuantity
          return item
        })
      }))
    } else {
      setCart(prevState => ({
        ...prevState,
        items: [
          ...prevState.items,
          {
            productId: products[productId - 1].productId,
            productSize: size,
            productQuantity: quantity
          }
        ]
      }))
     }
    }
    

    【讨论】:

    • 对此非常困惑。对于初学者,为什么将这些类函数设为常量?我在尝试这个答案时遇到了很多错误。感谢您的帮助,只是不确定如何实施。
    • 关于 const 你是对的,更新了。你能分享错误吗?我猜不出来。
    • 酷。所以我摆脱了 useState ,因为我的应用程序中已经有了一个状态。此外,将 const isProductExist 转换为箭头函数。然后,将 setCart() 更改为 this.setState()。接下来,我将返回项放在 if 语句之外,因为 .map 期望返回而不是 if 语句。然后只是修复了几个小的参考错误,比如购物车应该是 this.state.cartData。之后我没有收到任何错误。当我现在运行代码时,每个项目仍然被推送到我的列表中,即使它已经存在。我想知道 isProductExist 是否工作正常?
    • 知道了@Esther-I - 只是定位正确的财产。 product.productData.productId 而不是 product.productId!奇怪的是它从来没有给我一个参考错误。
    猜你喜欢
    • 1970-01-01
    • 2022-01-06
    • 1970-01-01
    • 2016-10-06
    • 2018-07-01
    • 2021-12-26
    • 2020-05-26
    • 2021-06-05
    • 2020-10-21
    相关资源
    最近更新 更多