单击按钮即可响应条件 setState

问题描述

所以,我完全不知道我希望它如何工作,但在我的脑海中,我认为它可能我似乎无法让它工作..

基本上我有一个空的对象数组:

this.state = {
     orders: [{}]
}

然后当我点击一个按钮时,我想要添加一个订单(自定义事件,因为购物车与点击的按钮没有父子关系,原因):

pubSub.on("addToCart",(data) =>
   this.setState((prevstate => ({
      orders: [...prevstate.orders,data.order]
   })
);

这有效。我最终得到:

orders: [
 {[sku]: sku,quantity: quantity}
]

现在我遇到的问题是,如果要使用阵列中已有的 SKU 添加订单,我只想更新数量。 如果在阵列中尚未找到 SKU,我想添加一个新订单。 所以我想检查数组中是否存在一个键(键 SKU 与键 SKU 的值相同)。

因此,要检查数组是否存在我将使用的键:

this.state.orders.map(obj =>{
  if (!(data.sku in obj)){
    **setState here with order added**
  }
})

我知道条件语句如果发现键存在,然后只更新数量

我面临的问题是它遍历数组中的所有订单,每次键不存在时,它都会添加一个新订单。 我怎么能做到这一点,所以它会检查密钥是否存在,如果是这种情况,则只添加新订单 1 次,而不是每次? 实际上,我想先检查所有密钥,然后再决定要做什么。 使用这种方法,我必须决定地图的每一轮应该做什么。

还要记住,我们处于自定义事件处理程序的范围内,我想在其中使用数据在这个处理程序中,我不能在 map 函数的范围之外分配变量。所以基本上它或者我只使用 setState,或者我使用 map 函数并在里面设置 setState。我不能同时使用它们,因为数据仅在第一个方法调用中可用。 这也是我第一次尝试使用这个自定义事件处理程序的东西,范围界定让我有点束手无策。

如果这是有道理的,并且有人能指出我正确的方向,那将不胜感激。 提前致谢!

解决方法

您可以在 setState 中传递函数。此函数将具有当前状态,如果您使用类,则将具有当前道具。在此函数中,您创建 state change - 要更新的状态对象的一部分。在您的情况下,它可能看起来像这样(它是准系统和肮脏的,以展示您如何做到):

// data is here,somwhere
this.setState(function(state,props) {
  let index = state.orders.findIndex(obj => data.sku in obj);
  if (index > -1) {
    // update existing
    return {orders: state.orders.slice(0,index).concat(
      {...state.orders[index],quantity: state.orders[index].quantitiy + 1},state.orders.slice(index+1))}
  } else {
    // create new
    return {orders: state.orders.concat(data)}
  }
})