[英]Bulk updating normalized Redux state
假設我已經像這樣規范化狀態(使用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為關鍵字的對象。
謝謝。
您可以將修改后的待辦事項存儲在對象中,然后使用擴展語法更新它
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;
}
};
我認為這是解決您問題的方法:
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;
}
};
我使用此解決方案是因為返回一個新對象並保留原始對象
你可以試試這個:
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;
}
};
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.