Understanding Redux, What ? When? Why ?

Rayhan Sattar
8 min readNov 13, 2018

What is Redux?

Redux is a library which is used to manage the predictable state. It provides a predictable state container for the JavaScript Apps. It is widely used in MVC based applications. It was developed by Dan Abramov.

What is Predictable State?

Predictable state is nothing but a “State Container” that holds all of your state. And it does not let you change the state directly instead it insist you to describe the changes which you want to made.These changes are called actions and its nothing more than an object containing the type of change you want in the state. It listens to your actions and performs the changes you want by help of some pure functions.

Motivation behind Redux

In the world of Single Page Applications, state management plays a vital role. All of your components needs to share the state to work perfectly. This state is managed by your code which also includes the Api calls to database for retrieving the data, or calls to write some data and many more things. We need to manage the state of each and every action like hiding and showing loader, pagination, activated routes and so on.

So this increases the complexity of your application’s state, so here the Redux come and play a great role in state management. Many of interface actions are easily managed by it and all the API calls are also easily integrated using Redux way of work.

When to use Redux?

  • When ever your application is too small so that it could handle its state within its scope, do not use Redux.
  • Redux is so helpful for larger scale applications. When data gets larger its really difficult to manage its state. That’s where Redux come.
  • Redux also makes code more modular which is also a big advantage.
  • If you are just learning React? Don’t make Redux your first choice. Handle the state within the components by sharing the state, when your learning is mature enough to develop large scale applications then give it a try!
  • Redux is not compulsory in your applications. It’s just like another tool in a developer’s tool belt.

Understanding the Architecture

Principles Of Redux

For understanding the architecture of Redux, It is divided into three parts..

  1. Single Source of Truth.
  2. The State of Redux is store is read only.
  3. All the changes are made up using Pure Functions also called Reducer.

Single Source of Truth ( Store Object )

This part of Redux is totally related to the way Redux store data. It creates a global object tree of your state within a single store. That makes your code more easy, durable and debug friendly. All of your application state is now a global tree object. Whenever a component or a part of your application needs that state? it can refer to the tree object.

Example :

// ===== global state ====== 
{
user : ‘user one’,
tasks : [ { … } , { … } , { … }],
}

In this particulate example, we have a simple state of containing a user and His/Her tasks. Now Its like a global store from which any component can retrieve data of user or can make changes to tasks. You can also manage this state within your components or application. I repeat, you can!!!

Redux State is Read Only

Redux state is read only. That means you can not manipulate the state directly. Instead you have to initiate an action that consist of an object containing what type of change we want in state.

The process starts from dispatching an action. This action tell Reducer ( a pure function ) to do some state manipulation with the state and then the updated state is returned on your view.

Change in state using a pure function ( Reducer )

As we know we can not change the state tree directly, instead we dispatch an action that tells a pure function to change the state. This pure function is known as Reducer Function. It takes the state and the action object as arguments and then we write some logic which is responsible for the state management and after that we return the updated state back to the view.

How it works :

There are three main building blocks of Redux.

1- Actions

2- Reducer

3- Store Creation

Lets jump into these building blocks one by one.

Actions

Actions are the information or the data you send to your application to store.
To elaborate actions, let me give you an example of bank. You go to bank and tell the manager to open you account. Now what happens ?
1- Manager listen to your action.

2- Manager perform some actions and create you account in the bank store.

3- Manager tells you back that the account is open now!

In the same way Redux works! You told the manager to open a new account and gave some details. This was an Action.
Actions are of two types: 1 — Synchronous Actions 2 — Asynchronous Actions
** we will look the synchronous actions first **

Actions are responsible for sending data to store. This is done by using a method called dispatch() which is available on storeobject.
A particular action consist of two things.

1 — type of change you want.

2 — The data you want to send to store. ( usually called payload )

example :

// action for creating an account in bank let details = {
name : 'Rehan',
age : 19,
gender : 'male',
status : 'student'
};
//actionlet openMyAccountAction = { type : 'OPEN_MY_ACCOUNT', payload: details };

we have successfully created out first Action. lets go to the next step!!

Reducer

A Reducer is a pure function which is responsible for the state manipulation. It takes a default state and your action object as an argument and perform some state management on it, then it returns the state. That’s why its called pure function.

In above bank example in actions section, the manager was your reducer. because it was taking your action and performing some changes to state of bank and then it was returning the new state.

// Reducer // creating default state for handling undefined case.
let defaultState = {
accounts : []
};
const manager = (state = defaultState, action) => {
// REDUX STATE IS READ ONLY!! so copy it in a newState, change // the new state and return that state!

let newState = { ...state };
// switch cases to match the action
switch( action.type ) {

case 'OPEN_MY_ACCOUNT':
newState.accounts = [ action.details, ...newState.accounts ];
break;
// many more cases
};

return newState;
};

If we break down the code into steps, this is actually happening :

1– First we have created a defaultState because when the state is initialized without it , it would be undefined! So avoiding the undefined state we are initializing it by an object containing a property accounts which is an array of accounts.

2 — In second step we are creating a normal function that is taking the state and action as an argument.

3 — Third step and the most complicated step for 90% student is copying the previous state. As I told you, Redux State is read only! You can’t manipulate state directly, instead you copy the whole state, change that new state and then return that state back to your view.

4 — switch case is for the correct match of action. You only want to open a new account so this case will be matched and then after it will move to the next step that is appending the accounts by a new document detail.Note that we are also getting all the previous accounts and adding the new account and returning a whole new array.

newState.accounts : [ action.details, ...newState.accounts ];

Then break will jump out the execution from switch body and finally we are returning the newState.

Congratulations you have successfully created a Reducer!

Final Step: Store Creation

creating a store is very simple we just have to call a function which Redux provide us. One and only createStore .

import { createStore } from 'redux';const store = createStore(manager); // takes reducer as argument. 

The first step is to import createStore from redux then the second step is to call it with the reducer you just created. In our case we have created a reducer named as manger so we are passing manager as argument.

we can also have multiple reducers. Like one is manager reducer and one is accountant reducer. We have slightly change syntax for it.

import { createStore, combineReducers } from 'redux';export default bankReducer = combineReducer( { 
manager, // manager reducer
accountant // accountant reducer
});
const store = createStore(bankReducer);

we have another function combineReducer who takes an object of reducers and combine them into a single reducer. That single reducer is passed to store.

congratulations! You have successfully complete third step!

You Redux store is ready now. Its time to dispatch actions.

let details = {
name : 'Rehan',
age : 19,
gender : 'male',
status : 'student'
};
//actionlet openMyAccountAction = { type : 'OPEN_MY_ACCOUNT', : details };store.dispatch(openMyAccountAction);

store.dispatch()is a method for dispatching an action. This action will go to the Reducer, Reducer will perform the state management and will update the store object, then the updated stage is returned.

Listening the Changes

Whenever your store tree is updated or there is any kind of change in it, or an action is dispatched, all these changers trigger store.subscribe() method. It listens to all the changes in store.
we can retrieve the updated data from store with the help of this listener.

Getting the updated State

For getting the state we can use another method store.getState();

store.subscribe(() => console.log(store.getState()));

now what is happening here is whenever the store is changed, we are getting the state from store. This is give us the updated state.

That’s all for Synchronous Redux flow!

Live code here :

** YOUR TASK **

1 — You have to create more actions such as updating account, deleting an account etc.

2 — You have to create the reducer switch cases for each action.

3 — You have to dispatch those new actions and test the state.

Conclusion

In this article we have covered the basics of Redux in details, like what is redux? When to use Redux? architecture of Redux, Flow of Redux with the help of a small example. We have covered the Synchronous flow and in the upcoming articles I’ll cover Asycn flow too. Stay tuned!
Happy Coding :)

#Perfect(Y)

--

--

Rayhan Sattar

Software Engineer | JavaScript, React, Next & Node