In this blog post, I want to introduce my latest open source project [ngrx-slice](https://github.com/nartc/ngrx-slice)
.
TLDR
ngrx-slice
provides the same functionalities as Redux ToolkitcreateSlice
provides- The goal is to reduce NgRx boilerplate, at least for simple feature states.
Run the following command to install:
- Consult documentations for usage details.
- Github repo available at ngrx-slice
What is ngrx-slice
?
ngrx-slice
is an NgRx plugin that provides almost the same functionalities that Redux Toolkit createSlice provides.
At this point, some of you might then ask “Hm… Chau, so what is createSlice
then?” createSlice
is dubbed, by Mark Erikson aka the author, as the modern way of implementing Redux in your JavaScript application, especially in ReactJS. The idea is to group most, if not all, Redux-related building blocks into a single slice of the global state. A slice has multiple layers which kind of represent multiple building blocks of a piece of State: Actions, Reducers, and Selectors.
Let’s take a look at the following Counter example in vanilla Redux:
Note that Actions, Reducers, and Selectors can be (and most of the time recommended) separated out into different files. So you might have: counter/actions.js, counter/reducer.js, and counter/selectors.js
Now let’s look at the same example with createSlice
API:
To learn more about this createSlice API, please refer to Redux Toolkit createSlice
You can already notice the amount of code is much less in createSlice
version with Actions being generated from the Reducers. Coupled with Immer for simpler state updates, the boilerplate becomes manageable.
ngrx-slice
embraces this same idea, but for NgRx
Why?
The main goal of ngrx-slice
is an attempt to reduce the amount of boilerplate of NgRx, at least for simpler features. A by-product goal of ngrx-slice
is to ease the learning curve to NgRx for React developers who now work with Angular and NgRx.
Imagine having the ability to reduce the following code (Counter example with NgRx):
The following effect is included for completeness. ngrx-slice
does not affect how you write your Effects.
The above snippets are pretty standard in NgRx world. Most of the time, you will have all of those files for each of your feature states. And to be honest, it does feel a bit overwhelming, especially for NgRx beginners. Let’s explore how ngrx-slice
can help with this.
How?
Installation
Like most things JavaScript/TypeScript, we start with installing ngrx-slice
ngrx-slice
depends onngrx-immer
andimmer
to allow for simpler state updates, just likecreateSlice
Implementing the Slice
Instead of the 3 different files for Actions, Reducers, and Selectors, you’d have a Slice file.
createSlice
,noopReducer()
, andPayloadAction
are imported fromngrx-slice
That’s all. Just like Redux Toolkit’s createSlice
, ngrx-slice
accepts a SliceOptions
object and returns the Reducer, generated Actions, and in addition the Selectors. For a more detailed explanation, please check out ngrx-slice Documentations
Using the Slice
The return value of createSlice
is an object with the shape { actions, selectors, name, reducer }
. With destructuring, CounterFeature
here is actually an object of { name, reducer }
, which is compatible with StoreModule.forFeature()
CounterSelectors
and CounterActions
are just namespacing the generated Actions and Selectors. With this, counter.effect.ts
can be modified like so:
You can see that for simple features like a Counter, all the logic is handled in a single counter.slice.ts
, and every building block is generated thanks to TypeScript.
Miscellaneous
Of course, there will be cases where more complex features do not benefit as much from ngrx-slice
but it does not mean you cannot use ngrx-slice
for those. The returned selectors
and actions
are just abstractions using createSelector
and createAction
under the hood. Hence, you can use/compose those like normal NgRx Selectors.
Entity is something tricky when used with ngrx-slice
. Supposedly, ngrx/entity helps with providing utilities to immutably update list data. With ngrx-slice
, you can update your list/array mutably with Immer. For example:
That is all. Go ahead and give ngrx-slice
a try. Feel free to reach out to me on Twitter @Nartc1410 if you have any questions or just want to chat, I’d love to hear from you. If you run into any issues, please feel free to open an issue on ngrx-slice Github. Thank you for reading.
Special Mentions
- Marko Stanimirović (@MarkoStDev) for
ngrx-child-selectors
and hiscreateFeature
PR - Tim Deschryver (@tim_deschryver) for
ngrx-immer
- Mark Erikson (@acemarke) for Redux Toolkit