Redux from scratch - A gentle approach.
Tags: redux, react, reducers, middlewares
Published: 2020-03-02 11:43:25

---
title: Redux from scratch - A gentle approach.
published: true
description: redux
tags: redux, react, reducers, middlewares
---
Redux stands out from the galaxy of libraries and frameworks by getting so many things absolutely right: A simple, predictable state model. An emphasis on functional programming and immutable data. A tiny, focused API...What's there not to like? Redux is a predictable state container for Javascript apps, in simple terms,  it is a place where we can have all our state in a Javascript application. Redux is very tiny, (2kb, including dependencies) and it can run in different environments (client, server, native).

This tutorial will guide you through building a full-stack Redux and immutable application. Through the course of this tutorial, you will learn a few things:
•	What is redux?
•	What redux include?
•	Implementation of redux
•	Create redux store with ReactJs
•	Adding actions and reducers to store
•	Combine reducers
•	Providers
•	Connects
•	Redux thunk
To better understand what redux is or what it does, let us first understand the problem redux helps us solve.

####Without redux
Suppose we have a root component(father) in react (fig 1), and this component has two child components(children), who in turn have 4 sub components(grand-kids). Now, suppose we have to pass some data from root component(father) to child component(grand-kids), we have to first pass through the (children) component, likewise when we need to pass data from (children) to parent component, it needs to flow through a callback function, so that callback function must first be passed down to any components that want to call it to pass data up. Imagine this was a bigger application, we are bound somehow to face some [prop drilling](https://kentcdodds.com/blog/prop-drilling). With REDUX, its like a central store, just like our grocery store where everything is available, users go there and purchase.  This redux store holds the state of our entire application where each component can directly call for the state and data from the redux store.
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/8v8azthk04d970p9t0ds.png)
####Structure of redux
Redux store-- The state of every redux application lives in the Redux Store, this store is central and accessible to every component. This store includes actions, actions are plain javascript objects just like this—{TYPE: “UPDATE_NAME”, NAME: kpose}. Then we have the REDUCERS, reducers are normal functions which get action. Put simply, reducers get information from the actions and update the state in the store. When using redux, there are three principles we should have at the back of our mind: 
1.	Redux store is a single source of truth – The data/state of our application must be stored in one place which is the REDUX STORE.
2.	State is read-only----This means that we cant change/mutate our state directly, this is why we need reducers.
3.	Changes are made with pure functions—Reducers

Now, lets go to the real coding part, for that we use [CodeSandbox](https://codesandbox.io/s/new) where you can follow along, i recommend you keep the [CodeSandbox](https://codesandbox.io/s/new) in sync with this tutorial and actually type out the examples as you go along.

###Create the Redux Store
In your CodeSandbox environment, expand the "Dependencies" section in the left pane, and click Add Dependency. Search for *redux*, add it, then click Add Dependency again and search for *react-redux* add *redux-thunk*, add them to your dependencies.
In a local project, you can install them with Yarn or NPM: 
`npm install --save redux react-redux redux-thunk`.
With redux installed, let's get our redux store ready. *Redux* comes with a function that create stores, and it’s called *createStore*.
In *index.js*, let’s make a store. Import *createStore* and call it like so:

```javascript
import React from "react";
import ReactDOM from "react-dom";
import App from './App'
import {createStore} from 'redux';

const store = createStore();

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);

```
and with that Redux *store* is ready, but we should notice some error in our console: 
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/a682tijbpji6ybwfdwyr.JPG)
The *createStore* accepts a *reducer* which is a function, this it does not have at the moment. We have to provide a function that will return the *state*, that is what the *reducer* does. So let’s make a really simple one, pass it into *createStore*, and see what happens, but before that lets first understand what a reducer is and how it helps us.
####What is a reducer in redux?
The **reducer** is a pure function that takes the previous *state* and an *action*, then returns the next or new state. Reducer function gets called with 2 arguments: it takes the current state, and an action, and returns the *newState*. Looks a lot like the signature of an [Array.reduce](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce) reducer. Redux reducers work just like the function you pass to Array.reduce! :) Reducers reduce actions, the difference is that with Array’s reduce it happens all at once, but with Redux, it happens over the lifetime of your running app. Edit our **index.js **to use a *reducer* like below:
```javascript
import React from "react";
import ReactDOM from "react-dom";
import App from './App'

import {createStore} from 'redux';

const nameReducer = (state, action) => {
  console.log('reducer', state, action);
  return state
}

const store = createStore(nameReducer, 
window.__REDUX_DEVTOOLS_EXTENSION__ && 
 window.__REDUX_DEVTOOLS_EXTENSION__());

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);

```
Notice we also added our Redux DevTools extension, after you make this change, open up the console, you should see a message logged there, something like this:
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/9yzssk0v7jvogeowxyws.JPG)
Remember, i said the *reducer*’s job is to take the current *state* and an *action* then returns the new state, it has another job, too: It returns the initial state the first time it’s called. This is sort of like “bootstrapping” your app (more like giving it a starting point). Let us give our app an initial state variable and use the ES6 default argument syntax to assign it to state.
```javascript
import React from "react";
import ReactDOM from "react-dom";
import App from './App'
import {createStore} from 'redux';

const initialState = {
  name: "kpose"
};

function nameReducer(state = initialState, action) {
  console.log('reducer', state, action);
  return state;
}
const store = createStore(nameReducer);

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
```
If you look at the console again, you’ll see it printed **{name: kpose}** as the value for state. That’s what we want.
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/6cnovp1zgcas8ha434n1.JPG)
Next, let's see how we can update our *state*.

####Updating state
For us to be able to update our *state*, we need to **dispatch** an **action**. An **action** is a plain Javascript object, with a minimum of two objects, a *type* and a *payload*. **Actions** are very free-form things. As long as it’s an object with a *type* it’s fair game. In order to make an action DO something, you need to *dispatch* it. The store we created earlier has a built-in function called *dispatch*. Call *dispatch* with an *action*, and Redux will call your *reducer* with that *action* (and then replace the state with whatever your reducer returned, or it's *payload*).

Let’s try it out with our store.
```javascript
...
const store = createStore(nameReducer);

//Dispatch action
store.dispatch({type: 'UPDATE_LASTNAME', payload:'Ganihu'})
store.dispatch({type: 'UPDATE_FIRSTNAME', payload:'Jude'})
console.log(store.getState())

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);

```
Every call to *dispatch* results in a call to your reducer!
Unfortunately, when we look at our console, we don't see any changes to our state, the name object in our state still has its value as "kpose" (its initial state). That’s because our *reducer* is not acting on those *actions* we dispatched. That’s an easy fix though. Let’s do that now.

######Properly Dispatching Actions
To make actions actually do something, we need to write some code in the *reducer* that will inspect the **type** of each action and update the *state* accordingly. Let's do that now:
```javascript
...
const nameReducer = (state = initialState, action) => {
  console.log("reducer", state, action);
  switch (action.type) {
    case "UPDATE_LASTNAME":
      return {
        name: action.payload
      };
    case "UPDATE_FIRSTNAME":
      return {
        name: action.payload
      };
   case "RESET":
      return {
        name: payload
      };
    default:
      return state;
  }
};
const store = createStore(nameReducer);

//Dispatch action
store.dispatch({type: 'UPDATE_LASTNAME', payload:'Ganihu'})
store.dispatch({type: 'UPDATE_FIRSTNAME', payload:'Jude'})
console.log(store.getState())

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
```
Try this out and take a look at the console.
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/1ol8fc8zrvo2x3prxyjl.JPG)
Hey look at that! The name is changing. This is just a simple store, i don't think it is too complicated. We just have to create our **store**, then create our **reducer** and an **action** that will be dispatched to update our state.

####Where does React come in?
Until now we have not done any react stuff, we have been doing strictly redux. Now its time to take a step further and see how we can **dispatch** **actions** and be able to update state from our react app. But before then, we will do a little clean-up. Create a new folder in your root directory, call it "redux". The redux folder will contain different files relating to redux, and we will start with the *store.js* file:

```javascript
Store.js

import { createStore, combineReducers } from "redux";
import nameReducer from "./reducers/nameReducers";

const reducer = combineReducers({name: nameReducer});
const initialState = {
  name: { name: "Kpose" }
};

const store = createStore(reducer, initialState, 
  window.__REDUX_DEVTOOLS_EXTENSION__ &&
   window.__REDUX_DEVTOOLS_EXTENSION__());

export default store;
```
Then we have the Actions and Reducers folders, which contains the *action* and *reducer* files respectively:

```javascript
//nameActions.js

const update_firstname = {
  type: "UPDATE_FIRSTNAME",
  payload: "Jude"
};

const update_lastname = {
  type: "UPDATE_LASTNAME",
  payload: "Ganihu"
};

const reset = {
  type: "RESET",
  payload: "Kpose"
};

export {update_firstname, update_lastname, reset };

```

```javascript
//name reducer
const nameReducer = (state = {}, {type, payload}) => {
  switch (type) {
    case "UPDATE_LASTNAME":
      return {
        name: payload
      };
    case "UPDATE_FIRSTNAME":
      return {
        name: payload
      };
    case "RESET":
      return {
        name: payload
      };
    default:
      return state;
  }
};

export default nameReducer;
```

```javascript
//index.js

import React from "react";
import ReactDOM from "react-dom";
import App from "./App";

//import store
import store from "./redux/store";

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
```
It is important to take note of *combineReducers* we encountered in store and understand why its there. Reducers know how to update the state by looking at the *type* of action coming in. The way reducers implement this logic is by using conditional statements. One popular way is to use a *switch* statement. In this case, our reducer manages changes to the application name, so it makes sense that one single reducer would handle all cases related to the name.But, what if we have unrelated aspects of our state to handle. What if our application had separate functionalities, like a user fetch, and a user update functionality?

Even though both these two functionalities deal with users, they have different responsibilities and, for the sake of making our application simpler and easier to maintain, it would be better to have separate reducers that handle these two functionalities separately.

We could name our reducers *nameReducer* and *userReducer* and put them into separate files inside the reducers directory.
But when we create a new Redux store with the *createStore* function, we can only pass one reducer to it. How are we supposed to fit two or more reducers as an argument to our function?

It turns out that Redux lets us combine multiple reducers into one that can be passed into *createStore* by using a helper function named *combineReducers*. The way we combine reducers is simple, we create one file per reducer in the reducers directory. We also create a file called *store.js* 
In the *store.js* file we import the *combineReducers* function from Redux and we also import all the individual reducer files.
We then invoke *combineReducers* and pass to it as an argument an object that contains all the individual reducers. *combineReducers* will combine all the reducers passed to it into a single reducing function that can then be exported as default. We don't have multiple reducers yet, but we will soon when we expand our application so i found it important to prepare you for any surprises.
At this point we have a lovely little *store* with a *reducer* that knows how to update the *state* when it receives an *action*. Now it’s time to hook up Redux to React.
To do that, the *react-redux* library we installed earlier comes with 2 things: a component called *Provider*, and a function called *connect*. By wrapping the entire app with the *Provider* component, every component in the app tree will be able to access the Redux *store* if it wants to.

In *index.js*, import the *Provider* and wrap the contents of *App* with it. Pass the *store* as a prop.
```javascript
//index.js
import React from "react";
import ReactDOM from "react-dom";
import App from "./App";
import { Provider } from "react-redux";
import store from "./redux/store";

ReactDOM.render(
<Provider store={store}>
  <App /></Provider>, 
document.getElementById('root'));
```
After this, our App, and all children of *App* – all of them can now access the Redux *store*. But not automatically. We’ll need to use the connect function on our components to access the store.
Next we will create a react component where we will be able to see result of dispatched *actions* and see the state updated real time. Lets create a *name.js* file then import them into our *App*.

```javascript
//Name.js

import React from "react";

function Name (props) {
  return (
    <div>
        <h2>Update Name</h2>
        <div>
          <button>Update First Name</button>
          <br/>
          <br/>
          <span
            style={{color:'blue'}}
            > NAME IS: </span>
            Name 
            <br/>
            <br/>
          <button>Update Last Name</button>
          <br/>
          <button>RESET</button>
        </div>
      </div>
  );
}
export default Name;
```
```javascript
//App.js

import React from "react";
import "./styles.css";
import Name from './Name'

export default function App() {
  return (
    <div className="App">
      <h1>Redux Crash course</h1>
      <div className="App">
      <Name />
      </div>
    </div>
  );
}
```
The buttons don't do much at the moment, lets change that. For us to be able to update our *state* when we press the buttons, we’ll need to use the *connect* function on our components to access the *store*.
`import { connect } from 'react-redux';`
Then we need to *connect* the Name component to Redux at the bottom:

```javascript
//Name.js
import React from "react";
import { connect } from "react-redux";
import {update_firstname, update_lastname, reset} from './redux/actions/nameActions';

function Name (props) {
  return (
    <div>
        <h2>Update Name</h2>
        <div>
          <button onClick={props.update_firstname}>Update First Name</button>
          <br/>
          <br/>
          <span
            style={{color:'blue'}}
            > NAME IS: </span>
            {props.name.name} 
            <br/>
            <br/>
          <button onClick={props.update_lastname}>Update Last Name</button>
          <br/>
          <button onClick={props.reset}>RESET</button>
          
        </div>
      </div>
  );
}

const MapStateToProps = (state) => {
  return {
  name: state.name
};
};
const MapDispatchToProps = (dispatch) => {
return {
update_firstname: ()=> dispatch(update_firstname),
update_lastname: ()=> dispatch(update_lastname),
reset: ()=> dispatch(reset),
}
};
export default connect(MapStateToProps, MapDispatchToProps)(Name);
```
####More on *connect*
Now that we have provided the redux store to our application, we can now *connect* our components to it. We established previously that there is no way to directly interact with the store. We can either retrieve data by obtaining its current state, or change its state by dispatching an *action*. This is precisely what *connect* does. Consider our code above, which uses connect to map the stores state and *dispatch* to the props of a component.
*mapStateToProps* and *mapDispatchToProps* are both pure functions that are provided the stores *state* and *dispatch* respectively. Furthermore, both functions have to return an object, whose keys will then be passed on as the props of the component they are connected to.
In this case, *mapStateToProps* returns an object with only one key : “name”, and mapDispatchToProps returns an object with the *update_firstname* and *update_lastname* keys.

The *connect*ed component (which is exported) provides *name*, *update_firstname* and *update_lastname* as props to **Name** component.

Phew! OK, now we should have our entire Redux cycle completely hooked up and running, and our app updates the state to our new "name" selection. Yes, yes, I know… it’s not the most styled up app of all time, but considering the boilerplate setup for Redux, let’s just stick to the concepts and feel free to style this up as you would like. But for now, pat yourself on the back and have a sip of coffee. Great work.
Up until now, we have been dealing with synchronous actions, our next challenge will be implementing an async action API fetch for user data information, we will be using data from [REQ | RES API] (https://reqres.in/). If you go to the website, you can see that we can get a request for user data from 
`/api/users?page=2`. Ready?

######What is Redux Thunk
Since reducers are supposed to be “pure,” we can’t do any API calls or dispatch actions from inside a reducer. We also can’t do that stuff inside a plain action creator! But what if we could make an action creator return a function that could do our work? Something like this:
```javascript
function fetchUsers() {
  return function() {
    return fetch('/current_user');
  };
}
```
Unfortunately, redux does not support actions like this, it only accepts plain objects as actions.
This is where *redux-thunk* comes in. It is a *middleware* for Redux, that enables Redux to deal with actions like *fetchUsers()*, above. You can *dispatch* these “thunk actions” like any other action creator: *dispatch(fetchUser())*.
A *thunk* is a name for a function that’s returned by another function. In Redux terms, the function being returned is the *thunk*, and the one that returns it is the *action creator*
The function you return from your action creator will be passed 2 arguments: the *dispatch* function, and *getState*. Most of the time you’ll only need *dispatch*, but sometimes you want to do something conditionally, based on some value in the Redux state. In that case, call *fetchState()* and you’ll have the entire state to read as needed.

######Fetching Data with Redux Thunk
First, lets add *redux-thunk* as a dependency. Then, in our *store.js*, import *redux-thunk* and apply it to the store with Redux’s *applyMiddleware* function. Just make sure to wrap thunk in the *applyMiddlware* call or it won’t work. Don’t pass thunk directly: 
```javascript
//store
import { createStore, combineReducers, applyMiddleware } from "redux";
import nameReducer from "./reducers/nameReducers";
import thunk from 'redux-thunk';

const reducer = combineReducers({name: nameReducer});
const initialState = {
  name: { name: "Kpose" }
};

const store = createStore(reducer, initialState, applyMiddleware(thunk), 
);

export default store;
```
Next, let’s go back to our actions folder and write out our fetch API code in a new file, called **fetchUsers.js**, and also have a **userReducer.js** file in our reducer folder.
```javascript
//fetchUsers.js
const fetchUsers = dispatch => {
  fetch("https://reqres.in/api/users")
    .then(res => res.json())
    .then(res => dispatch({ type: "FETCH_USERS", payload: res.data }));
};
export default fetchUsers;
```
```javascript
//userReducer.js
const userReducer = (state = [], { type, payload }) => {
  switch (type) {
    case "FETCH_USERS":
      return payload;
    default:
      return state;
  }
};
export default userReducer;
```
Back in our store, we can now import *userReducer*, add it to our *combineUsers*, set it to users, and set up its initial state, which will be an array. We also import *Thunk* and *applyMiddleWare* so that we can perform an async action using custom *middleware*. Edit our store to look like below, also notice our *combineReducers* in all its glory here taking our *nameReducers* and *userReducer* as arguments:
```javascript
//store.js
import { createStore, combineReducers, applyMiddleware } from "redux";
import nameReducer from "./reducers/nameReducers";
import userReducer from "./reducers/userReducer";

import thunk from "redux-thunk";

const middleware = [thunk];

const reducer = combineReducers({ name: nameReducer, users: userReducer });

const initialState = {
  name: {
    users: [],
    name: "Kpose"
  }
};

const store = createStore(
  reducer,
  initialState,
  applyMiddleware(...middleware)
);

export default store;
```
Alright! Now, let’s go back into our *Name.js* file and import our *fetchUsers* action. We can use the **map** method to map through our users and display the data by *dispatch*ing our fetch with a button. Our *Name.js* now looks like:
```javascript
//Name.js
import React from "react";
import { connect } from "react-redux";
import {
  update_firstname,
  update_lastname,
  reset
} from "./redux/actions/nameActions";
import fetchUsers from "./redux/actions/fetchUsers";

function Name(props) {
  return (
    <div>
      <h2>Update Name</h2>
      <div>
        <button onClick={props.update_firstname}>Update First Name</button>
        <br /> <br />
        <span style={{ color: "blue" }}> NAME IS: </span>
        {props.name.name}
        <br /> <br />
        <button onClick={props.update_lastname}>Update Last Name</button>
        <br />
        <button onClick={props.reset}>RESET</button>
        <br /> <br />
        <h2>Fetch Users</h2>
        <button onClick={props.fetchUsers}>FETCH USERS</button>
        {props.users.length === 0 ? (
          <p> No users yet </p>
        ) : (
          props.users.map(user => (
            <p key={user.id}>
              {" "}
              {user.id} - {user.first_name} - {user.email}
            </p>
          ))
        )}
        <br />
      </div>
    </div>
  );
}

const MapStateToProps = state => {
  return {
    name: state.name,
    users: state.users
  };
};
const MapDispatchToProps = dispatch => {
  return {
    update_firstname: () => dispatch(update_firstname),
    update_lastname: () => dispatch(update_lastname),
    reset: () => dispatch(reset),
    fetchUsers: () => dispatch(fetchUsers)
  };
};
export default connect(
  MapStateToProps,
  MapDispatchToProps
)(Name);
```
Awesome! Now, if we check back in our app and we click on our button to fetch users, we should see our users being fetched, our first and last names are also updated from state. 
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/34kyrc6a80ofg1h0vx7j.JPG)
You can check out what we have built so far on the codesandbox playground here https://codesandbox.io/s/clever-moser-qt5df

######Conclusion
I realize that there is a bit of set up involved here, but once we get the wheels in motion and we set things up in a way where we can observe our data management and have a store and see how our components are wrapped and listen to each other, the fundamentals for Redux start to make much more sense. This is a great starting point.
This is just a starting example for Redux and, hopefully, now that we’ve gone over some of the core concepts and seen them in action, this can help clarify a few things and start off a good launching pad to further our knowledge.
If you have any questions about the concepts or code, please leave me a message, a comment or can also reach out to me on [Twitter - @kpoosee](https://twitter.com/kpoosee) and I’ll get back to you. Cheers