How to Use Redux With React: A Step By Step Guide

Mdiouf
The Startup
Published in
9 min readSep 7, 2020

In this article, we’re going to see how to use Redux in your React application. We won’t focus on setting up your React application itself as I already wrote an article on it.

What is Redux and why use it

Here’s the definition of Redux: a state management tool for your application. In other words, Redux allows you to define one global store for your application. And every component can have access to that one store.

This concept is different from what you do with React. In fact, in React, every component has its internal state with no need for an external library.

So you would ask me: why do I need an external library to manage the state? Won’t it bring more confusion? To some extent, this can be true. I too would have asked the same question :-).

However, managing all these React internal states can be cumbersome. As you want to pass props to children components and vice versa (or sometimes children of children components). This is where Redux shines.

In Redux, there is one source of truth: the store

In Redux, your state is managed by one global store. And each component can have access to it, regardless of its relationship with the parent component.

There are other advantages to using Redux:

  • It’s not specific to React. You can use it with other frameworks like Angular or Vue.js.
  • It makes it easier to manage your application state, hence your application simply. I have tried to build applications in plain React. But using Redux is such an alleviation.
  • Having one state makes your application predictable, allowing you to implement login features. In this case, the source-of-truth (your data) lies in only one place: the store.

How Redux Works

As said, Redux allows you to have one global store that handles the state of your application. And every component can have access to that store.

Three building blocks make this ‘magic’ work:

  • The store
  • The actions
  • The reducers

Let’s look at the roles of every one of these:

The store

The store holds your application’s state. Like a cloud out there, or the sun, that each person (component) can see (have access to).

Actions

Actions are the only way to update your Redux store (changing information). And you update your store via the store.dispatch() function. Here’s an example of an action in Redux:

{
type: 'ADD_TASK',
text: "Do some coding at 8pm",
}

Note: an action will have a “type” property. This is how your store can be changed. Also, actions are mostly not just sent. They come from what we call action creators. Action creators are functions that help you create actions and send them. Like this one:

function addTask(task){return {type: ADD_TASK,task: task}
// or simply
return {
type: ADD_TASK,
task
}

Actions describe in general “what happened”. In our addTask example, we can say this happened:

A user wants to add a new task (type: ADD_TASK), with a text (task property)”.

Reducers

Reducers are functions that update your store, depending on the actions that were sent. When you use the dispatch function to dispatch an action, you are sending the information to the reducer.

The reducer will take that information, and do something, depending on the type property of that action.

A rule of thumb of a reducer is:

A function that accepts 2 things: an action and the previous state. It then returns a new state depending on the action type property.

If you understand this, things become crystal clear when you look at the reducer example I have set up for you ( see below).

Let’s say we want to add a new task to our Redux store. We can do this with the reducer following this logic:

  1. We first initialize our default store. So we create a new file called reducer.js and put this first line of code:
const defaultStore = {
tasks: [],
}

This will be your default store.

We then define our reducer (let’s call it taskReducer)

const taskReducer = (store = defaultStore, action) => {// Rest of the function}

This function is our reducer. You will write it right below the default store. Let me explain to you what is happening there:

  1. This reducer takes two parameters: the action, and the store.

It then returns a new state, depending on the type of that action.

Here’s now the taskReducer:

const taskReducer = (action, store = defaultStore) => {switch(action.type){
case 'ADD_TASK':
// do something
default:return store}

In the taskReducer function, we are using the switch statement to make our evaluation. We want to check the value of the action’s type (action.type) and do something if it’s the case.

Let’s continue with our function. We will now do something when the action we receive has a type of ‘ADD_TASK’. In this case, we want to add the task to our tasks array in the store.

const taskReducer = (action, store = defaultStore) => {switch(action.type){
case 'ADD_TASK':
// adding the task to our store
return
[...state,
tasks: tasks.concat(action.task)]
default:return store}

Inside the switch statement, we have a case of ‘ADD_TASK’. If the value of action.type equals to ‘ADD_TASK’, it will return the new state with the added task appended.

The return statement will trigger an update to the state.

Notice that we copied the previous state before appending the task. This is a Redux convention. You want to copy the previous state before you add or remove an element from that state.

The app listens to any change in your Redux store and updates itself

Any component that gets connected to one part or the entire store will re-render once it notices a change in the store.

This feature is powerful as it helps you define which component can have access to your state and how that component would re-render with the new information from that state.

Exercice: Real app implementation

In this section, you are going to build our first Redux store using React. After explaining to you how Redux works, let’s see it in action!

1. Create your react application

The first step is to create a React application (a simple to-do-list). I’m using VS Code but you can stick to your favorite code editor. Open your terminal and type:

create-react-app react-with-redux

This commands creates your React application in a folder called react-with-redux.

Open that folder with your code editor. (cd react-with-redux). We can now go to the next step, which is installing Redux.

2. Installing Redux in React

First, you need to install Redux in your app. Run the command:

npm install redux

In the second step, you need to install React-Redux. This package allows your React component to have access to the store.

npm install react-redux

3. Creating the store

After installing the redux dependencies, we can create our store. You do this in your index.js file in the src folder.

First, we import the createStore function from ‘redux’ (line 7 in the screenshot). This function creates the Redux store that holds the state. Remember, there should be one store in your application.

Then we create our reducer file. In your src folder, create a ‘reducers’ folder. Inside that new folder, create a new file called ‘reducer.js’.

This file will be our reducer for the application:

Now let’s create our store, in index.js. We have to import our reducer and use the createStore function to create our store.

Our store is ready. We can move to the next step which is to connect the redux store to our React application.

To do so, we need to import the Provider component from our react-redux package. We then wrap it to our App component. The Provider makes the Redux store available to any component:

Now our React app is connected with the store! However, there is something left which is: how can a specific component have access to the store?

Because connecting the whole React app to the store doesn’t mean every component “sees” it.

You need to define which component can have access to the store and which one cannot. For that you need two functions:

  • mapStateToProps
  • mapDispatchToProps

Using mapStateToProps to have access to the redux store

mapStateToProps allows your component to have access to the state. As the function name indicates, it maps the state to the props of that component. Let’s see it in action:

The mapStateToProps function takes the store (state) and maps it to a property (appState). That way, we can have access to it (step 2).

Notice we are using the connect function. This will help you ‘connect’ your App component to the redux store.

Also, we use destructuring in our App to have access to the appState property.

This is now the “state” of your App component. And your component will re-render every time the state changes.

Now can we change the state from our App component? The answer is yes, through another function we call mapDispatchToProps.

Using mapDispatchToProps to change the redux store

We create a function mapDispatchToProps to handle the store updates. Remember, we have to use the dispatch function for that:

This function takes a dispatch param and returns an object where a function (addTask) is mapped to the state. We can access that state using destructuring in App component.

What’s more convenient though would be to use a separate file and define action creators inside. That way, we can handle the adding task operation better. In actions.js (new file), let’s define our first action:

We get back to our App.js component and import that function to use it in our mapDispatchToProps function:

Here’s what’s happening:

(1) We import the addTask action creator from actions.js

(2) We remove the default content of App.js and replace it with a list of tasks available in our store. For that, we use the map function to return a paragraph for each task added to our app.

(3) & (4) We define a handleTask function that will query whatever is in the input text and call the addNewTask function.

(5) The addNewTask function is used in mapDispatchToProps as a way of dispatching the task using the addTask function.

This will in return send an action to our reducer with the type ‘ADD_TASK’

Handling the store update in our reducer

The store update happens in our reducer. For that, we need to use a switch statement to check the different values of the action type.

In this case, I added a default task to the initial state. Notice the appReducer is receiving an action and returns a new state in all cases.

If the action type is ‘ADD_TASK’, we return a copy of the previous state to keep everything as before, and only update the part we want. In this case, it’s the tasks property. Using the concatenation, we append the new task to the tasks array.

If we now try to add a new task from to our application, we have it added to our store and the app updates as well:

That’s it! You created your first React & Redux app. Redux can be challenging to understand and use. However, it offers powerful features and that’s the reason why you should learn it. For more clarification, take a look at its official documentation.

--

--

Mdiouf
The Startup

I am a full-stack developer with a passion for technology and learning new things. Founder of JavaScriptLearned.