Tidy Redux Reducers with Lodash FP
Tags: functional, redux, javascript
Published: 2019-07-24 10:49:46

---
title: Tidy Redux Reducers with Lodash FP
published: true
description: Use Lodash FP and function currying to write tidy reducers
tags: functional, redux, javascript
---

Lodash is the library I reach for most when writing JavaScript. In this post I'll show you how the functional programming (FP) build of Lodash can really tidy up your reducers.

To get started, import the functions that we'll use: `import {set, update, flow} from 'lodash/fp';`. Notice these are being imported from `'lodash/fp'`, not `'lodash'`.

Then have a look at this example:

```js
const reducer = (state, action) => {
  switch (action.type) {
    case 'SET':
      return set('some.deep.key', action.value, state);
    case 'INCREMENT':
      return update('some.deep.key', i => i + 1, state);
    case 'FOO':
      return flow(
        set('some.deep.key', action.value),
        update('another.deep.key', i => i * 2),
      )(state);
  }
};
```

Keen users of Lodash will see that the arguments for `set` and `update` are jumbled around! In the branch for `FOO` we only pass in two arguments, which is odd since we passed in three arguments earlier! What's going on?

The arguments are in a different order due to the FP build of Lodash. This build is not as well documented as the standard one, which is a bummer, but there are some docs available [here](https://github.com/lodash/lodash/wiki/FP-Guide).

> The lodash/fp module promotes a more functional programming (FP) friendly style by exporting an instance of lodash with its methods wrapped to produce immutable auto-curried iteratee-first data-last methods.

Hold on! It's not as scary as it sounds.

- *immutable*: Reducers must not modify the state, instead they must return a new state. Lodash FP and Redux go together like PB&J!
- *auto-curried*: A curried function takes a strict number of arguments. If it's given any less, it returns another function that takes the rest of the arguments before returning a value.
- *iteratee-first*: the "iteratee" is one of Lodash's superpowers. In our example, it's the dotted path inside of an object (our slice of state).
- *data-last*: the "data" in our examples is `state`. In normal Lodash, the data is usually the first argument.

If `set` is given a path and a value but not the state, it will return a function. That returned function takes one argument, the state, and then returns the new state. That's currying!

```js
const setNameToRobby = set('name', 'Robby');
setNameToRobby({ name: 'Robert', location: 'Wellington' });
// => { name: 'Robby', location: 'Wellington' }
```

Often I find that a given action will do a few things in a single reducer. This is where `flow` and curried functions comes in handy. `flow` takes a number of functions and returns a single function that composes them all together. A number of `set`s and `update`s (and others you might find useful in Lodash FP) can be given to `flow` as arguments and flow will produce a single function. That single takes in `state` and gives it to the first of the original functions, and the value out of the first feeds into the second and so on.

```js
flow(
  set('some.deep.key', action.value),
  update('another.deep.key', i => i * 2),
)(state); 
// is equal to:
update(
  'another.deep.key', 
  i => i * 2, 
  set(
   'some.deep.key', 
   action.value, 
   state
  ),
)
// and quite a bit more readable!
```