javascript - Integrera Immer med NgRx-reducerare
När man ser på redux och ngrx, verkar det som att immer är det rekommenderade biblioteket för att skapa en kopia av tillståndet innan det lagras. Följande immer-exempel, lägger jag till följande kod i min reducer:
on(exampleActions.updateExample, (state, { example }) => {
return produce((state: ExampleType, draft: ExampleType) => {
draft.push({ example });
draft[1].done = true;
});
})
Och TypeScript klagar på no-shadowed-variable, vilket strider mot exemplet. Dessutom kan jag inte returnera värdet utan return-typfel.
I fall där example är ett flernivåobjekt:
const example = {
a: {
b: { c: 1 }
}
};
draft behöver också vara helt avrefererad.
Det finns inte många exempel på immer och createReducer-integration eftersom detta är en ny förändring från 2019. Bör jag inaktivera regeln no-shadowed-variable för immer eller finns det ett bättre mönster för att försäkra att både state och example är ordentligt de-refererade. example är ett objekt med flera nivåer.
Alternativt kan jag undvika att använda immer och använda ramda clone eller försöka kopiera allt manuellt på djupet.
Svar #1
Detta är vad ngrx-etc löser, med mutableOn-funktionen (använder Immer)
const entityReducer = createReducer<{ entities: Record<number, { id: number; name: string }> }>(
{
entities: {},
},
mutableOn(create, (state, { type, ...entity }) => {
state.entities[entity.id] = entity
}),
mutableOn(update, (state, { id, newName }) => {
const entity = state.entities[id]
if (entity) {
entity.name = newName
}
}),
mutableOn(remove, (state, { id }) => {
delete state.entities[id]
}),
)
Källkoden kan hittas här, vilket du bör ta åt rätt håll.
