An Introduction to Redux

temitope emmanuel
The Andela Way
Published in
8 min readOct 4, 2017
Photo credit: Blake Connally

Introduction

Previously, I would get lost anytime I heard the word Redux! I used to say to myself;
“Oh! why do I have to use it? Why can’t I just write my actions right there before I render my components?”
So, I decided to research, and google my day out about “what is” and “what’s not” about Redux. All answers I got kept pointing to one thing…

Redux helps to manage state in applications!

I wondered what “State” really was! Fortunately, I found out after fervent research that “State” is where all the data that makes up our App what it is resides, and this “State” should be immutable. That simply means that a change in state doesn’t override the entire application state.

For example, take the case below;

// mutable
let a = [0, 1, 2];
let b = a;
console.log(b);n// b contains: [ 0, 1, 2 ]
b.push(5); // add an element to b
console.log(a); // a is affected thus: [ 0, 1, 2, 5 ]
console.log(b); // contents in b: [ 0, 1, 2, 5 ]

// immutable
let c = [0, 1, 2];
let d = c.concat(3);
console.log(c); // contents in c: [ 0, 1, 2 ]
console.log(d); // contents in d: [ 0, 1, 2, 3 ]

In the case above, we created an object and assigned it to the variable a. We then created another variable b and assigned the initially created object in a to it. Now, we have both variables a and b pointing to the same memory location. Mutability came in when we pushed 5 into the object assigned to b. Apparently, both variables a and b have the same value in memory. This is not what we wanted to achieve.

Furthermore, we created a variable c and assigned an object to it. We also created another variable d and assigned a simple action to it that adds another element to the object of c but does not mutate it. In this way, we successfully created a new object off c, with a remaining in tact and d pointing to a new object in memory. That’s just immutability in a nutshell.

You can find more on immutability here

Enough of all the intros, and let’s get started.

N.B: This tutorial assumes you already have some basic understanding of react. But, if you don’t, you’re still good to follow along as the parts containing react will be explained in briefly.

What is Redux?

Redux in simple terms is a manager that helps manage state in our application. It does so with Reducers, Actions, Store and State.

The Store is simply a store as the name sounds (very easy right?). It stores the entire state of our application.

The Action is simply a triggered event that requires something to change in the view. In order to have this change made in the view, a change in state is required. (Now you see how state makes our App what it is right?). Also, it is worth noting that an action should be unique i.e no two actions should be similar.

Now this Action that’s been triggered is passed down to the Reducer through something called the Dispatch (Will talk about this later on).

The Reducer takes in the Initial state or Default state. (Now, this part actually confused me a lot. Some tutorials had the default state set to an empty object, while some had it set to some initial values. After thorough consideration, I discovered that the whole thing is just a matter of preference. How you want your state to be like is totally up to you, depending on what an action is actually try to make happen.) After this, the Reducer acts on the State based on the type of action received and returns a new state with the previous state still intact.

Well, that’s about the summary of the entire introduction to Redux. Next is building the demo App.

We shall build a simple react application that consumes a certain API with create-react-app and we will manage its state using redux.

You should have the following installed in your PC

NPM(Node package Manager) or Yarn

create-react-app

After the above requirements have been met run create-react-app client then cd into client. Open the client folder and navigate to the package.json file. Currently we have our package.json looking like this

{
"name": "client",
"version": "0.1.0",
"private": true,
"dependencies": {
"react": "^15.6.1",
"react-dom": "^15.6.1"
},
"devDependencies": {
"react-scripts": "1.0.13"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test --env=jsdom",
"eject": "react-scripts eject"
}
}

So, copy the following and add it to the package.json file

"axios": "^0.16.2",
"react-redux": "^5.0.6",
"redux": "^3.7.2",
"redux-thunk": "^2.2.0",

And now our package.json file looking like this:

{
“name”: “client”,
“version”: “0.1.0”,
“private”: true,
“dependencies”: {
“react”: “15.6.1”,
“react-dom”: “15.6.1”,
“axios”: “0.16.2”,
“react-redux”: “5.0.6”,
“redux”: “3.7.2”,
“redux-thunk”: “2.2.0”,
},
“devDependencies”: {
“react-scripts”: “1.0.13”
},
“scripts”: {
“start”: “react-scripts start”,
“build”: “react-scripts build”,
“test”: “react-scripts test — env=jsdom”,
“eject”: “react-scripts eject”
}
}

Run npm install to install the application’s dependencies.
Yes… now we have all dependencies needed to run our mini App in place.

Next thing we’ll do is refactor our index.js file to suit the purpose of our App as it currently has React’s default code in it.

So first thing we’ll do is remove the lines of code we do not need so that our code will look like this:

import React from ‘react’; import ReactDOM from ‘react-dom’;
import { Provider } from ‘react-redux’;
import store from ‘./store’;
import App from ‘./App’;
ReactDOM.render( <Provider store = {store}> <App /> </Provider>, document.getElementById(‘root’) );

And now that we’ve done that, we also have to refactor our App.js file to something like this:

import React, { Component } from ‘react’;
import action from ‘./actions’;
import { connect } from ‘react-redux’;
class App extends Component {
render() {
return (
<div>heloo</div>
);
}
}
export default connect(null, { action })(App);

So going back to our index.js file we will be tying our top level component (which is App.js in this case) with react-redux’s provider.

Currently our index.js file looks like this:

import React from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux';
import store from './store';
import App from './App';
ReactDOM.render(
<Provider store = {store}>
<App />
</Provider>,
document.getElementById('root')
);

And after that we, create our store file, reducer folder and action folder in the src directory so we have the root looking like this:

./src

In our store.js file, we start by creating our store like this:

import {applyMiddleware, createStore } from 'redux';
import thunk from 'redux-thunk';
import reducer from './reducers';const middleware = applyMiddleware(thunk)
export default createStore(reducer,middleware)

In the above screenshot, we created our store using the redux’s createStore method. The createStore method takes in two values; reducer and middleware. The middleware (thunk) allows us to perform asynchronous actions wile the reducer is our imported variable containing all the reducers required in the app but in this case just one.

So now we will simply update our index.js file with the new changes below so our app can have access to the store

index.js

What we did here is simply import our created store in line 4, and passed it as a prop to the provider so all child components of the provider can have access to the store.

Next step is to update our App.js file to call an action from its prop.

App.js

Now we’ve done quite some work… first we imported connect from react-redux, and passed in two values; null and action. The null simply means we are passing an empty state from redux as currently we’re not expecting to see anything in App’s props and action which we also import from actions just so can make use of it in our App as a prop as shown in line 8. This action needs to be recognized by redux that’s why it’s first passed as a prop before usage since it won’t perform any action if passed directly.

Now that we’ve got our App.js file ready, next is to input some code in our action.js file. The following code contains the action.js with the updated code.

action.js

In the code above, clearly we first import axios since we will be making a request to an external server somewhere JSONPlaceholder, whose API we will be consuming for our asynchronous request. Next, we created a function called fetchApi() that dispatches our action to the reducer and also makes a get request via axios to our API.

You will see here that there are three dispatch actions GET_PHOTOS, which is fired immediately we make our request, GET_PHOTOS_SUCCESSFUL which is fired immediately we get a response from our API and FAILED which is fired when something goes on. So for each dispatch, our reducer makes changes to the state as expected. Next we will be talking about the reducer.

NB: The dispatch automatically sends an action to our reducer each time it’s fired as they are already connected in state.

reducer.js

The reducer like I said earlier on, is simply a function that takes in two values; an initialState and an action. We will be updating our reducer like the photo above:

Seeing from the photo, the reducer is actually a function like we said earlier that takes in our initialState which has been predefined above and an action which is an object passed down from the dispatch made in our fired action earlier. The action object contains a type key which the reducer uses to determine how to manipulate the stat and return a new state.

NB: The reducer requires a type key to be fired with our object else it will throw an error which is something we do not want in our application

Well that’s about everything, next is to see our App working. To do that, we will be using the redux Devtool which can be gotten from the chrome store. Following by a little configuration in our store.js by updating our existing code with this:

store.js

Now we are good to go. we can start our app by doing the following:

Run npm start in command line and wait for react dev server to load up.

Open chrome.

Navigate to http://localhost:3000/

Navigate to inspect element on your browser. We should see redux tab among our tab options if we installed its extension successfully like this:

inspect element

Select Redux and voila we should be seeing a nice looking environment like this:

redux showing state

That’s all for now. Feel free to play around with it, drop your questions, comments or criticism(wink) in the comment section below if there’s any and I’ll be sure to respond.

Thank you for reading and hope this has been helpful.

--

--