Immutable.js更新了深层嵌套的Map

时间:2018-01-15 13:43:12

标签: javascript redux immutable.js

我在更新redux商店时遇到问题。我在商店中有表格数据,更新补丁包含选择和要更新的值。商店的状态如下:

const state = fromJS({
  data: {
    rows: {
      row1: {
        col1: { amount: 1 },
        col2: { amount: 1 },
        col3: { amount: 1 },
        col4: { amount: 1 },
      },
      row2: {
        col1: { amount: 2 },
        col2: { amount: 2 },
        col3: { amount: 2 },
        col4: { amount: 2 },
      },
      row3: {
        col1: { amount: 3 },
        col2: { amount: 3 },
        col3: { amount: 3 },
        col4: { amount: 3 },
      },
      row4: {
        col1: { amount: 4 },
        col2: { amount: 4 },
        col3: { amount: 4 },
        col4: { amount: 4 },
      },
    }
  }
});

const newAmount = 5;

const selection = [
  { row: 'row1', column: 'col1' },
  { row: 'row1', column: 'col2' },
  { row: 'row2', column: 'col1' },
  { row: 'row2', column: 'col2' },
];

选择只能是一行或多行上的一个单元格或多个单元格。应使用相同的值更新每个单元格。更新商店的正确方法是什么,以便下一个状态看起来像这样。

const nextState = fromJS({
  data: {
    rows: {
      row1: {
        col1: { amount: 5 }, // updated with newAmount 
        col2: { amount: 5 }, // updated with newAmount
        col3: { amount: 1 },
        col4: { amount: 1 },
      },
      row2: {
        col1: { amount: 5 }, // updated with newAmount
        col2: { amount: 5 }, // updated with newAmount
        col3: { amount: 2 },
        col4: { amount: 2 },
      },
      row3: {
        col1: { amount: 3 },
        col2: { amount: 3 },
        col3: { amount: 3 },
        col4: { amount: 3 },
      },
      row4: {
        col1: { amount: 4 },
        col2: { amount: 4 },
        col3: { amount: 4 },
        col4: { amount: 4 },
      },
    }
  }
});

2 个答案:

答案 0 :(得分:1)

我能找到的最简单的方法(代码方式)是:

const newState = state.withMutations(newStore => {
  selection.forEach((selection) => {
    newStore.setIn(['data', 'rows', selection.row, selection.column, 'amount'], newAmount)
  }) 
})

这种方法的好处是你只需要迭代将要改变的东西。我不认为没有withMutation这样做是值得的,因为代码可能看起来很难处理。

答案 1 :(得分:-2)

我不知道Immutable.js但是当你处理对象不变性时,核心对象不会改变并且给你新的对象

因此,您可以在不使用immutable.js的情况下使用以下功能

 for(r in state.data.rows){
           for(var i=0 ; i < selection.length;i++){
                  if(r == selection[i].row){
                       for(c in state.data.rows[r]){
                          if(c == selection[i].column){
                              state.data.rows[r][c].amount = newAmount;
                          }
                       }
                   }
           }

        }

如果你想改变状态......