使用ES6,如何在for循环结束时返回?

时间:2017-05-11 15:00:50

标签: javascript ecmascript-6 redux immutability

我对Redux,es6,函数式编程和不变性都很新。由于我正在使用所有这些,我在redux应用程序中遇到了一些重大的困惑,我正在尝试构建。我遇到的问题是我正在尝试更新我的商店,但它只是更新了我的动作有效负载数组中的第一个元素。我知道这是因为我在for循环中做了返回。问题是,我不知道如何在for循环之外返回更新状态。

这就是我的减速机的外观:

function fruitsReducer(state = initialState, action){
  switch(action.type){
    case 'DEDUCT':
    //only updates one
    for(var actionID in action.payload){
      const actionFruit = action.payload[actionID];
      return {
        ...state,
        fruits: {
          ...state.fruits,
          [actionID]:{
            ...state.fruits[actionID],
            quantityRemaining: state.fruits[actionID].quantityRemaining - actionFruit.deduct
          }
        }
      }
    }
    default:
      return state;
  }
}

这是我的发稿:

dispatch({
  type: "DEDUCT", 
  payload: {
    0: {
      "itemName": "banana",
      "deduct": 1
    },
    1: {
      "itemName": "apple",
      "deduct": 1
    },
    5: {
      "itemName": "strawberries",
      "deduct": 1
    }
  }
})

这是我的商店:

{
  fruits: [
    {
      "itemName": "banana",
      "index": 0,
      "quantityRemaining": 10
    },
    {
      "itemName": "apple",
      "index": 1,
      "quantityRemaining": 5
    },
    {
      "itemName": "raspberry",
      "index": 2,
      "quantityRemaining": 2
    },
    {
      "itemName": "kiwi",
      "index": 3,
      "quantityRemaining": 15
    },
    {
      "itemName": "pineapple",
      "index": 4,
      "quantityRemaining": 1
    },
    {
      "itemName": "strawberries",
      "index": 5,
      "quantityRemaining": 3
    }
  ]
}

1 个答案:

答案 0 :(得分:1)

而不是for in循环,您可能希望map结果并将结果数组扩展到当前状态之上。我重写了你的reducer来映射有效载荷中的每个动作id。请注意我们如何在传播state.fruits之后传播地图的结果。

function fruitsReducer (state = initialState, action){
  switch (action.type) {
    case 'DEDUCT':
      return {
        ...state,
        fruits: [
          ...state.fruits.filter((fruit) => {
            return !Object.keys(action.payload).includes(fruit.index);
          }),
          ...Object.keys(action.payload).map((actionId) => {
              const fruit = action.payload[actionId];

              return {
                [actionId]: {
                  ...state.fruits[actionId],
                  quantityRemaining: state.fruits[actionId].quantityRemaining - fruit.deduct
                }
              }
            })
          ]
      }
    default:
      return state;
  }
}

注意:

您还可以为每个项目定义一个子减速器。一个很好的例子是@gaeron's todos code