Redux Setup and Overview. Today I’ll be discussing a React…
By: Cody Dupuis
Tags: React, Redux

Today I’ll be discussing a React library known as Redux. This post will cover a few different things, such as when and why you should use it, how to set it up, and basic usage.

Summary

Redux is a library used in React to manage state. The best use case for Redux is for larger applications, as setup and usage requires a few different working parts that is unnecessary for anything very simple. Redux can give your application a central hub of everything you’ll need to manage in your state through the Redux Store. The store is the core component that relies on other components such as actions, reducers, dispatch, and two different “mapToProps” methods.

Store

The first component of setting up Redux is setting up the Store. As explained above, the store is where your state will live. You will need access to the store in order to add, retrieve, change, and remove information. In order to visually see this info in your console, download the Redux DevTools from the Chrome Store’s extension.

// index.js import { compose, createStore } from 'redux'; const store = createStore(

rootReducer,

compose(

window.devToolsExtension ? window.devToolsExtension() :

f => f

)

) ReactDOM.render(

<Provider store={store}

<App />

</Provider>

Document.getElementById('root')

)

Let’s go over the pieces for a minute.

First, you import a couple of functions from Redux’s library, known as createStore() and compose() .

The first function, createStore() , does exactly what its name suggests. It accepts the reducer you’ll be using and the compose() function as the other argument. We’ll cover reducers in the next section.

The compose() function takes in a couple of arguments, one of which is an expression that enables the DevTools in your browser console. The other argument it would normally take is applyMiddleware() , which we aren’t using now. Check back later as I may write a post covering it!

Finally, we want to wrap our App component with the <Provider /> component, passing the store variable in as a prop.

Reducer

The reducer is a pure function that updates the Redux store’s state. The first thing I want to mention about this function is that when you update the state, you always want to make a copy of the updated state instead of modifying previous state.

A good convention to follow with reducers is to have a reducer for each resource you have. For example, a blogging app would have separate reducers for posts, comments, and users. These are all merged together into the reducer you saw above, called the rootReducer .

// reducers/rootReducer.js import { combineReducers } from 'redux';

import managePosts from './managePosts';

import manageUsers from './manageUsers'; const rootReducer = combineReducers({

managePosts, manageUsers

}) export default rootReducer;

Cool deal. So now, let’s dive into what the manageUsers reducer would look like:

export default function manageUsers(

state = {

currentUser: undefined

},

action

) {

switch (action.type)

case 'LOGIN_USER':

return {

...state,

currentUser: action.payload.user

}

case 'LOGOUT_USER':

return {

...state,

currentUser: undefined

}

default: return state;

}

}

Whoa, there’s a lot going on here. First-time Redux users will probably be a little intimidated by this, I know I definitely was. So with that, let’s break it down some:

In order to truly grasp what’s happening above, we need to cover Redux actions. An action is a simple JavaScript object that contains two keys: a type key to tell the reducer how to modify the state, and a payload key to show what it is we are trying to modify it with. So, assuming we have a user object that looks like this:

const user = { username: 'CTD', id: 1 }

Our action would look like this:

{

type: 'LOGIN_USER',

payload: user

}

So this is used when communicating with the API. Let’s assume we got that user object in a Promise returned from the API we communicate with. We then send that user as a payload in the action to our reducer, which then modifies the global Redux state. In order to modify that state, we need another function from Redux’s library.

Dispatch

The next core component of Redux is the dispatch() function. This function accepts an action as its argument. In the above example, lets assume we have that object set to a variable called action , our dispatch function is very simple:

dispatch(action);

OR

dispatch({ type: 'LOGIN_USER', payload: user});

mapDispatchToProps & mapStateToProps

The next thing we want to discuss is how to actually use everything we mentioned above within the context of our application. Enter these two concepts. In order to get to the preview, the first thing we need to import is the connect() function:

import { connect } from 'redux';

This function connects whatever component we have to the Redux Store. We then include it in the export:

export default connect(mapStateToProps, mapDispatchToProps)(App);

So what do these mapping statements look like? Please, allow me:

const mapStateToProps = (state) => {

return { currentUser: state.currentUser }

}

This variable above gives us access to the currentUser state that lives in our Redux store. As a result, anywhere within the App component now has access to the value of that state by using this.props.currentUser . If you’re familiar with React, you know that props are usually passed down to child components from parent components. In this sense, you can still do that with the currentUser prop we gained access to above, except now the parent component also has access to it. Think of it as Redux is now passing it as a prop through the Redux store.

Next, let’s look at using dispatch:

const mapDispatchToProps = dispatch => {

return {

loginUser: () => dispatch({ type: 'LOGIN_USER', payload: user })

}

}

What we are doing here is allowing our props to have access to an object with a key that points to a function. The key is essentially the name of the function and its value is an anonymous invocation of that function. As we saw above, dispatch takes in an action as an argument. Now, we have access to this.props.loginUser() anywhere in the App component and similarly to the mapStateToProps variable, we can also pass it down to children components as well.

Conclusion

I hope this was helpful in giving you a general idea of what Redux is, how it works, and why developers use it. I’ll be writing a follow up blog on how to actually implement using Redux. Thanks for reading, and happy coding!