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.

Relaterade artiklar