网络埋伏纪事

Redux Fundamentals: what is a reducer? — JavaScript Fatigue

网络埋伏纪事 · 2017-01-05推荐 · 99阅读 原文链接

When managing an application's state with Redux, one of the core concepts is that of the reducer function. But what is a reducer, and why is it called that? The answer is not unique to Redux and, as we'll find, reveals a useful pattern that can be applied in a lot of non-Redux JavaScript, and even in many other languages.

Reducing a list down to a single value

A core concept in functional programming is that we should use simple, pure, composable functions to derive the information we need from sets of values.

A very simple example of this concept would be looping over a list of values in an array and summing them together. This is probably the most common way to do that in JavaScript:

const list = [1, 2, 3];

let sum = 0;

for (let i = 0; i < list.length; i++) {
    sum = sum + list[i];
}

console.log(sum); // 6

But what if I wanted to write a function that adds numbers together so I can reuse it in several places? We could write an add function and update our loop above to call it.

const list = [1, 2, 3];

function add(a, b) {
    return a + b;
}

let sum = 0;

for (let i = 0; i < list.length; i++) {
    sum = add(sum, list[i]);
}

console.log(sum); // 6

That helps, but that for loop feels a little verbose for something we do so often. Array.prototype.reduce to the rescue! This is a function that you run on an array, where you pass it a function and a starting value and it runs that function on each value and reduces its values down to a single value:

const list = [1, 2, 3];

function add(a, b) {
    return a + b;
}

const sum = list.reduce(add, 0);

console.log(sum); // 6

Less lines of code, improved readability, and a reusable function! Wins all around.

What does this have to do with Redux?

We just established that a reducer is a simple function that takes two values and reduces them down to one value. That's all a reducer function is, even in Redux. It just so happens that the two values a reducer in Redux takes are the current state and an action that may (or may not!) update that state.

function counter(state = 0, action) {
    if (action.type === 'ADD') {
        return state + action.value;
    }
    return state;
}

In the example above, our reducer is a counter that takes two values: a state value--setting it to 0 if it's not provided--and an action object with type and value properties. The function reduces these two values down to a new value that Redux will store as the new state of the counter. If the action's type is not 'ADD' it will return the existing state.

And that's it! That's all a reducer is. In my next post, we'll look at how to store more than one piece of state in a Redux store by combining multiple reducers together.

But first...

What's so special about a reducer? It's just a function.

The fact that it is just a function is what's special about it! A simple function that does one thing well and has no side effects is easy to build, maintain and unit test. If you build applications that are highly interactive and require a lot of business logic to track state, this simplicity will help ensure you are able to quickly build, improve and change your app with a high amount of confidence and agility.

We'll talk more about this later, too!

相关文章