Redux and its core concepts with a simple example.

Redux is a state management library for frontend application. State of an application represents the application data and it controls the behavior of the application.

State of an application is the core part hence its management becomes essential for better application management and even crucial for large applications.

In its simplest form, redux provides very standard and predictable way to manage application state using few core concepts, let go through each of them. 

1: Actions: As the name itself is quite descriptive, it describes the action performed during application. A state of an application changes based on certain actions.  It's the only source of information for the redux store and is basically a javascript object with type property which describes the intent of the action, along with the payload or data that used by the reducers. e.g 

 

const actions = {
    CREDIT:'CREDIT',
    WITHDRAW:'WITHDRAW'
}

{type:actions.CREDIT,amount:200}

 

2: Action creators: It's a function which is used to enrich the actions with data and gives more control for handling data inside the actions.

const addCredit = credit => {
    return {
        type:actions.CREDIT,
        payload:credit
    }
}

3: Reducers: These are considered to be the only source to change or update the state of the redux store. It's a pure function which has a handler for each action type defined in the action and based on different action type the store is updated over here. It accepts initial state and action as parameters. 

Pure functions are free from all side effects with no external service call or global variable dependency. It only depends on the input parameters and returns the same output given the same input.

 

Note: Don't execute async operations inside reducers as reducer are meant to immediately update the state without any delay using the payload passed from the actions. 

An async operation should be done inside the action creators.

Don't mutate the state of the application and this is the core principle of redux.

e.g:

let rootReducer = (state = initialState, action) => {
    switch(action.type){
       case actions.CREDIT:
       return {
           ...state,
           balance: state.balance + action.amount
       } 
       break;
    case actions.WITHDRAW:
        return{
            ...state,
            balance: state.balance - action.amount
        }
        break;
    default:
    return state;

}}

 

Redux flow:

Let's go through the simplest example of redux as a stand-alone library. 

 

Step 1: Initialize a node project using the command inside any folder.

npm init

 

Step 2: Accept all the defaults, package.json will be created inside the current folder, after that install the redux dependency.

npm install redux --save

 

Step 3: Create a javascript file index.js and save the mentioned below code to see the usage of redux.

 

let redux = require('redux'); // pull in the redux library

let createStore = redux.createStore; //assign reference to createStore function from redux


// initial state with data as balance
let initialState = {
    balance: 500
}

//actions
const actions = {
    CREDIT:'CREDIT',
    WITHDRAW:'WITHDRAW'
}

//action creators
const addCredit = credit => {
    return {
        type:actions.CREDIT,
        amount:credit
    }
}

//reducers

let rootReducer = (state = initialState, action) => {
    switch(action.type){
       case actions.CREDIT:
       return {
           ...state,
           balance: state.balance + action.amount
       } 
       break;
    case actions.WITHDRAW:
        return{
            ...state,
            balance: state.balance - action.amount
        }
        break;
    default:
    return state;

}}

let store = createStore(rootReducer); // initialize the store with rootreducer

console.log(store.getState()); // get the current store state

// a subscribe method which is called on each update to state
store.subscribe(() => {
    console.log("[subscription]", store.getState());
})

store.dispatch({type:actions.CREDIT,amount:200}); // using inline actions 
store.dispatch(addCredit(100));// using action creators
store.dispatch({type:actions.WITHDRAW,amount:300});
// console.log(store.getState());

 

Once the store is initialized on #46 with reducers as an argument, we have special methods available to play with the redux store.

#31 uses es6  spread operator to update the state of the application in an immutable way. The operation creates a new copy of the object by updating only the balance property.

This can be achieved in es5 using Object.assign function. 

Object.assign({},state,{balance:state.balance + action.amount})

 

1. subscribe: Used to subscribe to state changes inside the redux store.

2. getState: Used to get the current state of the redux store.

3. dispatch:  Used to dispatch actions to reducers to update the state.

Run the above code by execution

node index.js

 

Enjoy coding.