ngrx/store reuse reducer logic

Written by luukgruijs | Published 2017/04/23
Tech Story Tags: angular2 | ngrx | angularjs | javascript | rxjs

TLDRvia the TL;DR App

When your application grows, you may find several parts of your stores doing the same kinds of work for different types of data, ideally we want to reduce duplication by reusing the same common logic for each data type. It can also happen that you want to have multiple “instances” of the same type of data.

Let’s say that we’re creating an application that has two pages which each display a list of users. Each list displays a different set of users, for example: administrators or editors. Each list can be sorted and we can select a user. Reducers for the pages can possibly look like this:

First the administrator reducer.

Then the editor reducer:

After that we can use combineReducers to setup our state

For each reducer we’ve done a few things:

  1. Since we’re using typescript we first setup an interface for our state.
  2. We then define our initial state
  3. After that we define our reducer with it’s action types

While there is nothing wrong with each individual reducer, this code is not really DRY. Since the structure of each reducer is exactly the same, we can abstract the code and create one reducer that can be used by both the administrator and the editor state.

Abstracting your reducer code

We can make our reducer more abstract by using user in the keys of our state, instead of editor or administrator. Our reducer can then possibly look like this:

Setting up our state can then be done like this

There however is a problem with this setup. Since combineReducers will call each reducer that has the same action. If we would dispatch an action of {"type": "sort"} it will actually sort both the administrator and the editor state, not just the one you would like to sort. In order to achieve the desired behavior we need some way to wrap the reducer logic so that we can ensure that only the reducer we care about is updated. This can be achieved using a higher-order reducer function.

Using a higher-order reducer

A higher-order reducer is a function that takes a name as an argument and returns a new reducer function as a result. We can use this pattern to create new instances of a reducer. This higher-order reducer might look like this:

We can now use this function in our combineReducers function to generate multiple instances of the reducer:

Now suffix your action names so they correspond with the new names in your reducer and your good to go.

Conclusion

Using the higher-order reducer pattern we are able to dispatch actions that will affect only the portion of the state that we care about and we can create multiple instances of our data in a DRY way. We prevent duplication of reducer logic which results in a more maintainable codebase.

Thanks for reading. In my next post I will write about reusing effect logic. This was my first post, any feedback? Let me know.

Follow me on Medium and let’s connect on LinkedIn


Published by HackerNoon on 2017/04/23