redux

Previously in my “React-Redux for Newbies” series I discussed the value of using Redux in a React app and provided a high level overview of reducers. In this article I will cover Redux actions and the role they play in a React-Redux environment. If you need a refresher about why applications use Redux or the intent of reducers, please review the earlier posts from this series.

Before jumping into what actions are, let’s set the landscape of where actions live in React-Redux.

redux actions

As displayed in the diagram above, actions sit between our React view and our Redux reducer. Thinking about the general definition of an action and combining that with our understanding of reducers, this diagram seems logical. In order for an action to take place, a user must trigger an event on the UI. We know that reducers take the current state and an action as arguments to update the store. Finally our React components re-render based upon the updated version of our store.

What are Redux actions?

Actions are JavaScript objects that contain a “type” property. If you remember, when we created our reducer it contained a switch statement based on the action type. The reducer updates the store based upon action type. This is how a simple Redux action looks:

{type: ‘ADD_RECIPE’}

If we are creating a recipe book application and this action was triggered we would expect a new recipe to be added to our store. As is, our action would not be able to do that. We are missing the recipe information. A more functional version of our add recipe action would like this:

{type: ‘ADD_RECIPE’, recipe: recipe}

Where we include the recipe we are adding. Now in our reducer if our recipe book is an array of recipe objects we can just concat the recipe book with the new recipe.

Redux Connect

In order for our actions and components to have access to our store we must connect our React components to the Redux store. In Redux, we use the connect function to do so. The connect function maps our Redux state and actions to properties that are accessible by our React components.

Connect has four optional arguments mapStateToProps, mapDispatchToProps, mergeProps, and options.

mapStateToProps passes state as the first argument to our mapStateToProps function. Enabling us to connect our component properties to our state, which will update our component whenever there are changes to the state. We can pass null or undefined as the first argument to prevent our component from being notified of store updates. However, if we intend to subscribe to updates we must ensure our mapStateToProps functions returns an object like shown below.

const mapStateToProps = (state) => {
    return {
        recipes: state.recipes
    }
}

The second argument mapDispatchToProps passes dispatch as the first argument to our mapDispatchToProps function. This function is what we will use to dispatch our functions and notify the store of changes. This parameter does not have to be a function, it can be an object or undefined depending on your needs. Like mapStateToProps, mapDispatchToProps must return an object. The object properties should contain functions that dispatch actions. For this example, we will make it a function:

const mapDispatchToProps = (dispatch) => {
    return {
        addRecipe: (recipe) => dispatch({type: ‘ADD_RECIPE’, recipe: recipe})
    }
}

The other two parameters we will ignore in this article. Before discussing about dispatching action, I would like to point out that the connect function returns a Higher Order Component which we use to wrap the component we intend to connect to the store.

Dispatching Redux Actions

Actions are dispatched based on user interaction and interact directly with the reducer. The reducer accepts an action and the current state as arguments and updates the state accordingly. Then the reducer returns an updated version of the state. Simply put, actions signify an update to the state is needed.

In Redux we can dispatch actions in two ways, within our component directly or using mapDispatchToProps. If we pass null or undefined to mapDispatchToProps within connect, dispatch will be passed to our component as a property by default. We dispatch actions within our component like:

onClick={() => props.dispatch({type: ‘ADD_RECIPE’, recipe: recipe})}

Using mapDispatchToProps like we defined earlier, our component no longer needs reference to dispatch. Therefore we will dispatch actions like so:

onClick={props.addRecipe}

Redux Action Recap

Redux actions are JavaScript objects with a 'type' property that informs us that a specific event has occurred within our application. When dispatched, we can update our application's store and perform other business logic based upon the action type or any other information that is included within our action. In order to connect our actions and reducer to our store, we must use the Redux connect function.

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

React-Redux for Newbies: Dispatching Redux Actions
Tagged on: