What is a Redux reducer?
Published: 2018-03-23 11:55:22

---
title: What is a Redux reducer?
published: true
tags: 
canonical_url: https://daveceddia.com/what-is-a-reducer/
---

> **reducer** , _n._ – A word Redux made up to confuse you.

In order to write Redux code, you need to know a few things. One of those things is what a **reducer** is and what it does. It might seem a bit scary and foreign, but after this short article I think you’ll come to agree that it is, as the saying goes, “just a function.”

First off, where does the name “reducer” come from? Redux didn’t actually make it up (I was kidding about that). It might not seem too foreign if you’re familiar with functional programming and JavaScript’s `Array.reduce` function. And if you know `Array.reduce`, you know that it takes a function (one might call it a “reducer” function) that has the signature `(accumulatedValue, nextItem) => nextAccumulatedValue`.

## Array.reduce is like a sister to Redux

If you aren’t yet familar with `Array.reduce`, here’s what’s up:

JavaScript’s Array has a built-in function called `reduce`.

(_Technically_ I should be writing it as `Array.prototype.reduce`, because it is a function on _array instances_, not on the capital-A `Array` constructor.)

It takes a function as an argument, and it calls your provided function once for each element of the array, similar to how `Array.map` works (or a `for` loop, for that matter). Your function gets called with 2 arguments: the last iteration’s result, and the current array element. This will make more sense with an example:

```
var letters = ['r', 'e', 'd', 'u', 'x'];

// `reduce` takes 2 arguments:
// - a function to do the reducing (you might say, a "reducer")
// - an initial value for accumulatedResult
var word = letters.reduce(
  function(accumulatedResult, arrayItem) {
    return accumulatedResult + arrayItem;
  },
''); // <-- notice this empty string argument: it's the initial value

console.log(word) // => "redux"
```

In this example, the reducer will get called 5 times (because there are 5 elements in the array). The calls go like this:

- first called with `('', 'r')` =\> returns `'r'`
  - the empty string `''` comes from the 2nd argument to `reduce`, and the `'r'` is the first element of the array
- then `('r', 'e')` =\> returns `'re'`
  - the ‘r’ comes from the previous return value, and ‘e’ is the next element of the array
- then `('re', 'd')` =\> returns `'red'`
  - the ‘re’ is the previous return value, and ‘d’ is the third array element
- then `('red', 'u')` =\> returns `'redu'`
  - by now you are sensing a pattern
- then `('redu', 'x')` =\> returns `'redux'`
  - the pattern is all too clear now

The last return value, `'redux'`, is returned as the final result and stored in the `word` variable.

## Redux Reducers

Now that you know how `Array.reduce` works, I can tell you that Redux is _basically_ a fancy Array.reduce function (ok ok that’s a huge oversimplification, but bear with me).

A Redux reducer function has this signature:

`(state, action) => newState`

As in: it takes the current `state`, and an `action`, and returns the `newState`. Looks a lot like the signature of an Array.reduce reducer, eh? Remember:

`(accumulatedValue, nextItem) => nextAccumulatedValue`

Plainly speaking, a Redux reducer gets to decide how each action affects the state. Let’s look at an example one:

```
function wordReducer(state = '', action) {
  switch(action.type) {
    case 'ADD_LETTER':
      return state + action.letter;
    case 'RESET':
      return '';
    default:
      return state;
  }
}
```

Quick quiz: is there any Redux-specific code in here? Anything that depends on the Redux library to work? Go ahead, think it over, I’ll wait.

…

…

…

Answer: Nope! This is a plain old function. Sure, it takes `(state, action)` arguments and returns a new state. And it expects `action` to look something like `{type: 'ADD_LETTER', letter: 'r'}`. But none of that is particularly _bound_ to Redux.

### How it Works

But anyway, what does it actually do? Let’s try calling it with a few things and see what it returns.

```
let state = '';
console.log(wordReducer(state, {type: 'ADD_LETTER', letter: 'y'}));
  // => y
console.log(wordReducer(state, {type: 'ADD_LETTER', letter: 'y'}));
  // => y
console.log(wordReducer(state, {type: 'ADD_LETTER', letter: 'y'}));
  // => y
```

First: notice that `wordReducer` does not _remember_ anything. It holds no state within.

```
let state = '';
console.log(wordReducer(state, {type: 'ADD_LETTER', letter: 'a'}));
  // => a
console.log(wordReducer(state, {type: 'ADD_LETTER', letter: 'b'}));
  // => b
console.log(state)
  // => ''
```

Next: notice that `wordReducer` does not _change_ the state. It merely returns a new one. It treats state as _immutable_. This is important because, by updating state in an immutable way, Redux is able to tell which pieces of state changed, and optimize how your app is re-rendered.

One more thing:

```
console.log(wordReducer(undefined, {type: 'UNHANDLED'}));
  // => ''
console.log(wordReducer('existing state', {type: 'UNHANDLED'}));
  // => 'existing state'
```

Notice that the reducer has an initial state (when given `undefined`, it returns an empty string anyway), and that it has a `default` case that handles any actions it doesn’t understand (it returns the existing state, unchanged, when it sees such an action).

### Pilot Needed

I can tell you don’t think this is very useful. What good is a function that doesn’t remember anything, and doesn’t change anything?

I’ll tell you: This function is nice because it is _predictable_. If you call it with the same arguments, you get the same outputs, every single time. It doesn’t matter what else has changed in your app – this function will always act the same way.

It is easy to figure out what it does by reading its code (and easy to debug!) because it’s all self-contained.

Now, the downside with a function like this is that it needs a _driver_ of sorts. Something needs to hold on to the intermediate state, otherwise the app won’t really do much of anything.

The driver, in this case, is Redux. Specifically, the Redux store. It does something like this:

```
let state = '';
state = wordReducer(state, {type: 'ADD_LETTER', letter: 'a'}));
state = wordReducer(state, {type: 'ADD_LETTER', letter: 'b'}));
state = wordReducer(state, {type: 'ADD_LETTER', letter: 'c'}));
```

The store maintains an internal `state` variable. When an action is dispatched, the store calls the reducer, and replaces its internal `state` with whatever the reducer returned. Every time the store calls the reducer, it passes in the last-known state.

Around and around it goes: Redux sitting there waiting for an action, handling that action, updating the state, re-rendering your app, on and on forever.

So that’s it! That’s how Redux reducers work, in a nutshell. Not too bad?

[What is a Redux reducer?](https://daveceddia.com/what-is-a-reducer/) was originally published by Dave Ceddia at [Dave Ceddia](https://daveceddia.com) on March 19, 2018.

[CodeProject](http://www.codeproject.com)