使用List更改ImmutableJS嵌套对象并返回整个状态(Redux)

时间:2017-09-29 09:40:06

标签: javascript redux react-redux immutability immutable.js

我的州是一个嵌套的不可变的东西:

const state = Map({ counter: 0, 
                    people: List([
                        Map({name: "John", age: 12, etc...}),
                        Map({name: "Jim", age: 13, etc...}),
                        Map({name: "Jack", age: 21, etc...})
                     ])
                  });

所以我有一张地图,里面有一个计数器和地图列表。我在这里简化了一些事情,但是我想在我的减速机中改变John的一些属性。

现在我正在做这样的事情:

    var newState = state
                .get('people') //get the list
                .get(action.payload.pos) //pos is an integer, & describes the position of the object in the List
                .set('name', action.payload.name)
                .set('age', action.payload.age);

我的问题是我不知道如何在John 中设置属性并恢复整个状态,所以我可以在我的reducer中返回它。现在我回来的只是我正在改变的部分。

第二个问题是将所有这些写下来的很长的路要走。我知道嵌套结构有一种语法,但我这里有一个List,这会打破这种情况,所以我有点卡住了。

1 个答案:

答案 0 :(得分:2)

您可以使用.findIndex查找要更新的索引(如果您还没有),然后在.updateIn调用中使用索引,并与.merge一起使用合并旧值和新值。

const state = 
  new Immutable.Map({ 
    counter: 0, 
    people: new Immutable.List([
        new Immutable.Map({name: "John", age: 12, otherVal: 'a'}),
        new Immutable.Map({name: "Jim", age: 13, otherVal: 'b'}),
        new Immutable.Map({name: "Jack", age: 21, otherVal: 'c'})
     ])
  });
  
const newValues = { name: 'Jones', age: 100};

// find index to update
const indexToUpdate = state
  .get('people')
  .findIndex(person => person.get('name') == 'Jim');
// use .updateIn to perform a merge on the person of interest
const newState = 
  state.updateIn(
    ['people', indexToUpdate],
    person => person.merge(newValues)
  );
  
console.log(
  'new state is:\n', 
  JSON.stringify(newState.toJS(), null, 2)
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/immutable/3.7.2/immutable.min.js"></script>