Understanding Reducers

Understanding Reducers

Pure functions and Immutability

What is Reducer?

Reducers, as the name suggests, take in two things: previous state and an action. Then they reduce it to one entity: the new updated instance of state.

Reducer function has 2 properties. They are:

  1. Reducer must be a pure function.
  2. Reducer maintains immutibility.

What is pure function?

A function is called pure function if it always returns the same result for same argument values and has no side effects like modifying a variable outside its scope. The only result of calling a pure function is the return value. Examples of pure functions are strlen(), pow(), sqrt() etc. Examples of impure functions are printf(), rand(), time(), etc.

Example-1:

const a = (b, c) => {
    return b + c;
};

Note: Pure reducer is needed so that state updates become predictable.

What is immutability?

Immutability means something that can not be changed. Immutability of redux state is necessary since it allows detecting redux state changes in an efficient manner. This implies that whenever we want to modify a redux state, we must create a new copy of it and do modifications to that copy - which then becomes the new redux state.

Note: Primitive data type like variables are immutable and reference data type like array, object are mutable. Although there are some array methods that do not change the original array like array.may(), array.filter(), array.find() and so on.

Why Reducers are called reducer?

Reducer is called reducer since it reduces a collection of events distributed over time and an application state. It does it the same way as array.reduce() function with only one difference - arrays are static, while collection of events are distributed over time.

Example-2:

const array = [1, 2, 3, 4, 5];

const result = array.reduce((previousResult, currentValue) => {
    return previousResult + currentValue;
}, 0);

console.log(result); // Output: 15

Here we see that the reducer function takes an big array and converts it into a single value. Now lets see next example.

Example-3:

const initialState = {
    value: 0,
};

const actions = [
    { type: "increment", payload: 1 },
    { type: "increment", payload: 1 },
    { type: "increment", payload: 1 },
    { type: "decrement", payload: 1 },
];

const counterReducer = (state, action) => {
    if (action.type === "increment") {
        return {
            ...state,
            value: state.value + action.payload,
        };
    } else if (action.type === "decrement") {
        return {
            ...state,
            value: state.value - action.payload,
        };
    } else {
        return state;
    }
};

const finalResult = actions.reduce(counterReducer, initialState);

console.log(finalResult); // Output: {value: 2}

We can see that without using redux, just using vanilla js we achieved similar result. Here, the reducer() is reducing the action array and given an updated state as a output, which is like array.reducer in the first example-2. For this reason, the Reducer in redux is called reducer.

Conclusion:

In this article we discussed about reducer and its properties. Additionally, we discussed why reducers are called reducers.

Thank you for reading.

If you find this helpful, leave a like, share, and follow me, @srafsan to read more articles.