If you need to update an element in an array in your store, you need to copy the array and clone the corresponding element to apply your changes.
So, in the first step, your action should contain either an already cloned (and modified) object, or an object identifier and mutable properties.
Here is an example:
export class MyActions {
static readonly UPDATE_ITEM = 'My.Action.UPDATE_ITEM';
static updateItem(id: string, changedValues: any) {
return { type: MyActions.UPDATE_ITEM, payload: { id, changedValues } };
}
}
export const myReducer: Reducer<IAppState> = (state: IAppState = initialState, action: AnyAction): IAppState => {
switch (action.type) {
case MyActions.UPDATE_ITEM:
return { ...state, items: merge(state.items, action.payload) };
default:
return state;
}
}
const merge = (array, change) => {
const index = array.findIndex(item => item.id === change.id);
array = [...array];
if(index >= 0) {
const existingItem = array[index];
array[index] = { ...existingItem, ...change.changedValues };
} else {
array.push = { id: change.id, ...change.changedValues };
}
return array;
}
source
share