Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Integrate Immer with NgRx reducer

Looking at the redux and ngrx, it looks like immer is the recommended library to produce a copy of the state before storing. Following the immer example, I add the following code to my reducer:

  on(exampleActions.updateExample, (state, { example }) => {

    return produce((state: ExampleType, draft: ExampleType) => {
      draft.push({ example });
      draft[1].done = true;
    });

  })

And typescript complains no-shadowed-variable, which conflicts with the example. Additionally, I am unable to return the value without return-type errors.

In cases where example is the a multi-level object:

const example = {
  a: {
    b: { c: 1 }
  }
};

draft need to be fully de-referenced as well.

There isn't a lot of examples of immer and the createReducer integration as this a recent change for 2019. Should I disable the no-shadowed-variable rule for immer or is there a better pattern to confirm that both the state and example are properly de-referenced. example is an object of multiple levels.

Alternatively, I can avoid using immer and use ramda clone or attempt to manually deep-copy everything.

like image 812
Dan Avatar asked Dec 05 '25 17:12

Dan


1 Answers

This is what ngrx-etc solves, with the mutableOn function (uses 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]
  }),
)

The source code can be found here, which should you take to the right direction.

like image 82
timdeschryver Avatar answered Dec 07 '25 05:12

timdeschryver