160

Simple immer-base function to be used in NgRx Store or ComponentStore for transforming data "mutably"

Friday, November 20, 2020

Immutability is the cornerstone for the performance in Angular Applications. NgRx is no exception there. However, sometimes it is difficult or error-prone to try to construct the new immutable state by yourself when multiple levels of spreading is involved (e.g. with Indexable inside) and/or adjusting a value within deeper nested Array.

immer to the rescue!

Now, do we use it?

For that here's a simple three-LoC-function that I found to be very useful.

Checkout the live example at Stackblitz.

Code Examples

mutableReducer

import { Draft, produce } from "immer";

/**
 * Wrapper to simplify usage immer with Reducers/Updaters.
 *
 * @ngrx/store example:
 *  ```ts
 *  on(action,  mutableReducer((draft) => {
 *    draft.val = true;
 *  })),
 * ```
 * @ngrx/component-store example:
 *  ```ts
 *  readonly setPageIndex = this.updater(mutableReducer(
 *    (state, value: string | number) => {
 *       state.pageIndex = Number(value) || 0;
 *  }));
 * ```
 *
 */
export function mutableReducer<T, V>(
  callback: (state: Draft<T>, value: V) => T | void
) {
  return (oldState: T, value: V) => {
    return produce(oldState, (state: Draft<T>) => callback(state, value)) as T;
  };
}
Alex Okrushko

Principal UI Architect at Cisco (ex-Google, Firebase) NgRx team @AngularToronto organizer

Discussions are healthy ❤️