如何使用嵌套对象编写状态reducer

时间:2016-02-20 00:58:49

标签: javascript redux

我的redux状态树的心智模型看起来像这样:

{
  selectedDepartment: 'Chemistry',
  purchasesByDepartment: {
    Chemistry: {
      purchaseOrders: {
        ...
      },
      invoices: {
        ...
      }
    },
    Biology: {
      purchaseOrders: {
        ...
      },
      invoices: {
        ...
      }
    },

    ...(another department, etc)
  }
}

这是我的减速机

const purchasesByDepartment = (state = {}, action) => {
  switch (action.type) {
    case RECEIVE_POS:
      return Object.assign({}, state, {
        [action.department]: {
          purchaseOrders: action.json
          // but this wipes out my invoices          
        }
      })
    case RECEIVE_INVOICES:
      return Object.assign({}, state, {
        [action.department]: {          
          invoices: action.json
          // but this wipes out my purchaseOrders
        }
      })

    default:
      return state
  }
}

您可以在每个部门看到,我有一个purchaseOrders和一个发票键。 我尽力编写我的减速机,这样它不会改变我的状态,但我没有运气,因为每个动作都会消除另一个键。

我发起了两个动作:RECEIEVE_POS,RECEIVE_INVOICES。

当我的行动RECEIVE_POS被调度时,我可以创建一个包含采购订单的新状态,但这会清除我的发票。

当我的行动RECEIVE_INVOICES被分派时,我可以创建一个带发票的新州,但这会清除我的采购订单。

如何编写我的减速机,以便我可以保留我的采购订单和发票(如果它们已经存在于我的州内)?

3 个答案:

答案 0 :(得分:2)

您可以先应用更改为部门创建新状态,然后将其合并到reducer状态。

immutablejs

就个人而言,我喜欢使用return state.setIn([action.department, 'purchaseOrders'], action.json]); 使我的整个商店不可变,这使得这样的操作(和其他一些东西)变得微不足道:

def genarator(x, y):
    square = x * y
    matrix = [[]]
    matrix2 = []

    i = 0    
    while square > 0:
        j = 0
        while x > j:
            matrix[i][j] = int(raw_input("Enter the matrix number"))
            j = 1
        i = 1
        square = -square
        matrix2 = matrix2 + matrix

    return matrix2


def main():    
    matrix3 = []
    x = int(raw_input("Enter the width of your matrix"))
    y = int(raw_input("Enter the Length of your matrix"))
    matrix3 = genarator(x, y)
    print(matrix3)
    return 0

main()

答案 1 :(得分:1)

我使用spread运算符(表示为...arrayName)来实现此目的。这是es6,我用babel启用了功能。

Spread会将数组展开到其元素中,因为它比Object.assign更具人性化。

使用您的上下文,对于我的reducer中的一个简单场景,我就像:

return {
    ...state,
    selectedDepartment: 'Chemistry or whatever' 
}

这将返回一个由state组成的数组,以及用给定值覆盖的selectedDepartment。

对于嵌入式对象,您可以这样设置:

return {
    ...state,
    purchasesByDepartment: {
        ...state.purchasesByDepartment,
        Chemistry: {
            ...state.purchasesByDepartment.Chemistry,
            invoices: {
                {your new invoices object comes here}
            }
        }
    }
}

答案 2 :(得分:0)

对象传播计算属性名称相结合帮助我解决了这个问题

case RECEIVE_POS:
  return {
    ...state,
    [action.department]: {
      ...state[action.department],
      purchaseOrders: action.json
    }
  }
case RECEIVE_INVOICES:
  return {
    ...state,
    [action.department]: {
      ...state[action.department],
      invoices: action.json
    }
  }