Given the same input, pure functions always return the same output. Because reducer functions are pure, given the same state and action, they are always going to return the same new state. This makes them predictable.
The following code defines an impure function, because subsequent calls with the same input result in different output:
var i = 0
function impureCount () {
i += 1
return i
}
console.log(impureCount()) // prints 1
console.log(impureCount()) // prints 2
As you can see, we are accessing a variable outside of the function which is what makes the function impure.
We could make the function pure by specifying i as an argument:
function pureCount (i) {
return i + 1
}
console.log(pureCount(0)) // prints 1
console.log(pureCount(1)) // prints 2
Pure functions should only work with their input arguments and constants. For reducer functions, being pure means that all nontemporary data should be stored in the state object.
Reducers in Redux are always pure functions. They take the previous state and an action as arguments and return a new state object. The new part is important here. We never modify the passed state directly, because that would make the function impure. We always need to create a new state object based on the old state.
In our reducer function, we used Array.concat to create a new array from the old state array, adding the new post at the end:
function postsReducer (state = [], action) {
switch (action.type) {
case 'CREATE_POST':
return state.concat([{ user: action.user, text: action.text }])
default:
return state
}
}
You might think that such a reducer function will become very complicated, as it deals with the whole application state. Usually, you start out with a single simple reducer. As your application grows, you can split it up into multiple smaller reducers, each reducer dealing with a specific part of the application state. Because reducers are just JavaScript functions, it is easy to combine them, pass additional data, and even make reusable reducers for common functionality, such as undo/redo or pagination.