假设我已经像这样规范了状态(使用normalizr)
entities: {
todos: {
'aaa': {
id: 'aaa',
text: 'Todo A',
completed: false
},
'bbb': {
id: 'bbb',
text: 'Todo B',
completed: false
},
'ccc': {
id: 'ccc',
text: 'Todo C',
completed: false
}
}
}
然后我有一个从服务器获取ID的操作,已完成。对于该动作类型,我有这样的reducer:
const todos = (state = initialState, action) => {
switch (action.type) {
case ActionTypes.FETCH_COMPLETED_SUCCESS:
return {
...state,
todos: action.payload.completedIds.map((id) => {
return {
[id]: {
...state.todos[id],
completed: true
}
}
})
};
default:
return state;
}
};
如果我收到一个带有''aaa','ccc']的数组(可能是真实应用程序中的数千个项目),我想在单个动作中将“completed”设置为TRUE,是吗?可能的?
我当前的reducer实现不起作用,因为它返回一个对象数组,而原始规范化状态是ID为关键字的对象。
感谢。
答案 0 :(得分:3)
您可以将修改后的待办事项存储在对象中,然后使用扩展语法(如
)进行更新const todos = (state = initialState, action) => {
switch (action.type) {
case ActionTypes.FETCH_COMPLETED_SUCCESS:
let newTodos = {};
action.payload.completedIds.forEach((id) => {
newTodos[id]: {
...state.todos[id],
completed: true
}
})
})
return {
...state,
todos: {
...state.todos,
...newTodos
}
};
default:
return state;
}
};
答案 1 :(得分:0)
我认为这是解决问题的方法:
const todos = (state = initialState, action) => {
switch (action.type) {
case ActionTypes.FETCH_COMPLETED_SUCCESS:
return {
...state,
todos: Object.keys(action.payload.completedIds).reduce((previous, current) => {
previous[current] = {
...state.todos[current],
completed: true
}
return previous;
}, {})
})
};
default:
return state;
}
};
我使用此解决方案,因为返回一个新对象并保留原始对象
答案 2 :(得分:0)
你可以试试这个:
const todos = (state = initialState, action) => {
switch (action.type) {
case ActionTypes.FETCH_COMPLETED_SUCCESS:
const newState = {};//New Object
const filterKeys = Object.keys(state).filter( key=>{
newState[key]=state[key]; //copy
return completedIds.indexOf(key)!=-1;
});
filterKeys.forEach(key=> newState[key].completed = true);
return newState;
default:
return state;
}
};