# Higher-Order Reducers in Redux

In Resetting Redux State we’ve seen a way to reuse reducer logic to reset the state by creating a root reducer. But that’s not the only way to reuse reducer logic, and higher-order reducers come into the scene to help us with reusability and reducing code duplication.

Higher-order reducers, unlike the root reducer approach, allow us to apply a certain functionality to the reducers that need it. They do so using functional composition, so let’s first learn that concept.

## Higher-Order Function

A higher order function is a function that returns another function as its result. For example, if we have a plain function with the following two arguments:

``````const greet = (first, second) => console.log(first + second)

greet('Hi ', 'little kitty'); // Hi little kitty
``````

We could re-write it in a higher-order function by separating their arguments in two nested functions:

``````const greet = first => second => console.log(first + second)

greet('Hi ')('little kitty'); // Hi little kitty
``````

Notice the call to `greet('Hi ')` function, which returns a function that we are calling as `('little kitty')`. The point is, this approach allow functional composition for code reuse.

Why doing that, you say? Imagine you want to use the `greet` function to say Hi \${someone} several times in your code. If you do it with a simple plain function as the first example, you’ll need to repeat `Hi` several times:

``````greet('Hi ', 'dolphin');
greet('Hi ', 'camel');
greet('Hi ', 'snake');
``````

While using a higher order function, we have the ability to easily create a `sayHi` function:

``````const sayHi = greet('Hi ');

sayHi('dolphin 🐬');
sayHi('camel 🐫');
sayHi('snake 🐍');
``````

You can already see two benefits:

• We’re creating a more semantic `sayHi` function based on a more generic one
• We’re not repeating `'Hi '`

Of course, this is a simplistic example that’s merely for education purposes, but that `greet` function could be something which performs heavier logic, where the mentioned benefits will be much more obvious.

## Higher-Order Reducers

Now you understand the mechanics of a higher-order function, you might be wondering: how’s that related to reducers? Well, if you think about it, a reducer is simply a function, so when we apply this pattern to reducers we call them higher-order reducers.

Let’s go over an example. Imagine that you have a users and articles reducers, which have a `data` property that comes from an API. Something like:

``````const defaultState = {
data: []
};

const userReducer = (state = defaultState, action) => {
//...
}
``````

Say that both of the users and articles need to have pagination. Then we’ll need to have some actions like `GO_NEXT_PAGE`, `GO_PREV_PAGE`, `UPDATE_TOTAL_PAGES`, etc. It becomes really cumbersome when you need to duplicate all that logic in each of your reducers that need pagination.

Here’s where we can create a higher-order reducer that, given a reducer, returns a decorated reducer with the additional functionality. Let’s call it `withPagination`:

``````const withPagination = reducer => (state, action) => {
switch(action.type) {
case 'GO_NEXT_PAGE':
return { ...state, page: state.page + 1 }
// ...
default:
return reducer(state, action);
}
};
``````

Isn’t this familiar? Yes, the nested function is a reducer. Remember that a reducer has the `(state, action)` signature.

What’s happening here is that, based on a `reducer` given as an argument, we’re returning a new reducer function that adds the `GO_NEXT_PAGE` logic, and on the `default` statement of the switch, we simply are proxying the call to the original reducer. So with this, we’re adding some functionality only when needed.

## Using a Higher-Order Reducer

We can apply the already created `withPagination` higher-order reducer to the reducers we’d like, for example when calling the `combineReducers` function to create the app’s root reducer:

``````import { combineReducers } from 'redux';

import withPagination from './higher-order-reducers/withPagination'

import users from './reducers/users';
import articles from './reducers/articles';

const rootReducer = combineReducers({
users: withPagination(users),
articles: withPagination(articles),
// ...
});
``````

Notice that we’re applying the pagination logic only to the `users` and `articles` reducers. That’s the power of higher order reducers: we can apply them as needed.

## Parametrizing Higher-Order Reducers

We still have a problem with the previous example: when we trigger the `GO_TO_NEXT_PAGE` action, both the `users` and `articles` will handle that actions since they both are checking the same action name.

As you can guess, that can be solved by specifying different action names for different reducers, so we’ll have the `USERS_GO_TO_NEXT_PAGE` and `ARTICLES_GO_TO_NEXT_PAGE` actions.

We can make that happen by passing a section parameter to the `withPagination` higher order reducer:

``````const withPagination = (section, reducer) => (state, action) => {
switch(action.type) {
case `\${section}_GO_NEXT_PAGE`:
return { ...state, page: state.page + 1 }
// ..
}
};

// ...

const rootReducer = combineReducers({
users: withPagination('USERS', users),
articles: withPagination('ARTICLES', articles),
});
``````

## Wrapping Up

We’ve seen the higher-order reducer pattern and how it solves code duplication and improves reusability by using function composition.

I hope you’ve learned something new here, and that you can see how there are multiple patterns we can apply to Redux or our code in general given Redux’s functional nature.

Stay cool 🦄

🔎 Searching...