如何使用 ImmutableJS 更新 List 中的多个元素?
How to update multiple element inside List with ImmutableJS?
您好,我正在使用 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);
});
}));
但它对我不起作用,没有更新任何东西
中创建了一个类似的解决方案
您错过了 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())
请参阅更新后的 fiddle http://jsfiddle.net/djj6u8xL/399/
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 变成不可变映射的不可变列表。
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;
}));
所以我设法通过映射列表然后查找 listItem 是否存在于 action.contacts 中来解决它。如果它匹配我 return 与 loading: true
匹配的对象,如果不匹配我 return 相同的对象。
我乐于接受如何重构此解决方案的建议,我对不可变 js 很陌生,我觉得有更简单的方法来解决这个问题,但我还不知道。
您好,我正在使用 immutableJS,如果数组中的多个对象具有与 action.contacts
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);
});
}));
但它对我不起作用,没有更新任何东西
中创建了一个类似的解决方案您错过了 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())
请参阅更新后的 fiddle http://jsfiddle.net/djj6u8xL/399/
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 变成不可变映射的不可变列表。
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;
}));
所以我设法通过映射列表然后查找 listItem 是否存在于 action.contacts 中来解决它。如果它匹配我 return 与 loading: true
匹配的对象,如果不匹配我 return 相同的对象。
我乐于接受如何重构此解决方案的建议,我对不可变 js 很陌生,我觉得有更简单的方法来解决这个问题,但我还不知道。