In the first part of my “React-Redux for Newbies” series we discussed why Redux is used. In short, Redux simplifies state management in React applications. For this installment, we will dive into the inner workings of Redux and discuss reducers. This article will explain what a Redux reducer is and how it works within React.

What is a Redux reducer?

As we discussed in the previous section of this series, Redux is a state container that holds the most recent version of your application’s state. In Redux you must use reducers to update your store or application’s state.

Creating a Redux store

The first thing you must do is create a store to hold the state of your application. Creating a store looks something like this:

import { createStore } from ‘redux’

const store = createStore(reducer)

In the code above, we created a store to hold our application’s state tree and specified the reducer that will be used to interact with our store.

Creating a Redux reducer

A reducer is a pure function that takes the current state and an action as arguments and returns a new version of the state.

export default function reducer (state, action) => {
    switch (action.type) {
        case actionTypes.AddRecipe:
            return {
                ...state,
                recipes: recipes.concat(action.item)
            }
        default:
            return state
    }
}

As you can you see above, we have created a reducer that takes the state and an action as arguments. Inside of our reducer, we update the state of our app based on the action type and return it. To ensure our reducer upholds the principles of a pure function, we return a new version of the state instead of mutating it. Hence the use of the object spread operator and array concatenation.

Initializing our state

When a store is created a dummy action is triggered to initialize the state. The initial state of our application will be “undefined” because we have not specified a preloaded state within createStore and we are not handling undefined states within our reducer. When initialized, the default case of our switch statement will be executed in which we return the state as is.

There are two ways we can handle the initialization of our state. We can pass a preloaded state into createStore or set a default value for our state parameter within our reducer. Below we will initialize our state tree using a default parameter in our reducer.

const initialState = Object.freeze({
    recipes: []
})

export default function reducer (state = initialState, action) => {
    switch (action.type) {
        case actionTypes.AddRecipe:
            return {
                ...state,
                recipes: recipes.concat(action.item)
            }
        default:
            return state
    }
}

Conclusion

At this point, you should know what a Redux reducer is and how to create one. In the next part of this series, I will discuss actions and how they interact with reducers to update our state tree.

Have more questions about React-Redux? Contact us or checkout our other posts about React-Redux.

About the author