更新状态->对象->数组->对象

时间:2020-03-19 21:15:08

标签: javascript arrays reactjs object setstate

在深度嵌套的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的另一种产品时,它并不能仅仅增加数量,它会创造出另一个对象。

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

p.s。 出现我在沙箱中无法通过localhost获得的错误,因此这里不是一个真正的选择

2 个答案:

答案 0 :(得分:0)

我没有尝试运行代码(如果您提供codeandbox或类似的东西,那么会做),但这应该会有所帮助。

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 }]
                }
            }))
        }
    }
}   

答案 1 :(得分:0)

有效。希望对您有帮助。 (为更井井有条的代码进行一些更改):

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
      }
    ]
  }))
 }
}