如何使用ImmutableJS更新List中的多个元素?

时间:2017-10-05 04:49:38

标签: reactjs immutable.js

您好我使用的是immutableJS,如果action.contacts具有相同的ID,我想更新数组中的多个对象

const initialState = fromJS({
  list: [{
    id: 1,
    loading: false,
  }, {
    id: 2,
    loading: false,
  }, {
    id: 3,
    loading: false,
  }]
});

action.contacts = [{
  id: 1
}, {
  id: 2
}]

我预计当我调用state.get(' list')时它会等于

  list: [{
    id: 1,
    loading: true,
  }, {
    id: 2,
    loading: true,
  }, {
    id: 3,
    loading: false,
  }]
到目前为止我所做的是:

case UNLOCK_CONTACTS:
    const indexesOfRow = state.get('list').findIndex((listItem) => {
      return action.contacts.map((contact)=> listItem.get('id') === contact.id)
    })

    return indexesOfRow.map((index)=> {
      state.setIn(['list', index, 'loading'], true);
    });
  }));

但它不适合我,没有更新任何内容

我在小提琴http://jsfiddle.net/xxryan1234/djj6u8xL/398/

中创建了一个类似的解决方案

3 个答案:

答案 0 :(得分:0)

您错过了immutable.js的观点。对象不可变。

const initialState = Immutable.fromJS({
  list: [{
    id: 1,
    loading: false
    }, {
    id: 2,
    loading: false
    }, {
    id: 3,
    loading: false
    }],
});

const contacts = [{
    id: 1
}, {
    id: 3
}]


let newState = initialState.set( 'list', initialState.get('list').map( (row,index) => {

  let contact = contacts.find((item)=>{
    return item.id == row.get('id')
  })

  if (contact){
    return row.set('loading', true)
  }
  return row;
}))

console.log(newState.toJS())

请参阅更新的小提琴http://jsfiddle.net/djj6u8xL/399/

答案 1 :(得分:0)

const newState = initialState.update('list', (oldValue) => 
                  oldValue.map(item => 
                    action.contacts.find(act => 
                      act.get('id') === item.get('id')) !== undefined ? 
                       item.update('loading',(oldVal)=> !oldVal) : item))
  console.log(newState.toJS())

注意:您需要将action.contacts转换为不可变映射的不可变列表。

答案 2 :(得分:0)

case UNLOCK_CONTACTS:
  return state.set('list', state.get('list').map((listItem) => {
    const matched = _.find(action.contacts, (contact) => listItem.get('id') === contact.id);
    if (matched) {
      return fromJS({ ...listItem.toJS(), loading: true });
    }
    return listItem;
  }));

所以我设法通过映射列表来解决它,然后查找list.tem是否存在于action.contacts中。如果匹配,我将匹配的对象返回loading: true,如果不匹配,则返回相同的对象。

我愿意接受如何重构这个解决方案的建议,我对不可变的js很新,我觉得有更简单的方法可以解决这个问题,但我还不知道。