Introduction to Redux library

Cecilia Benítez
5 min readFeb 19, 2021

Redux is a library to control the state of our web applications easily, in a consistent way between client and server, testable, and with a great development experience.

Redux is largely influenced by the Flux architecture proposed by Facebook for React.js applications and by the Elm language, it is very designed for React.js, but it can also be used with Angular.js, Backbone.js, or simply with Vanilla JS.

Principles

Redux is based on three principles.

A single source of truth

All the status of your application is contained in a single store.

This makes it easy to debug our application and create universal applications whose state on the server can be serialized for later use in the browser without much effort. Other functionalities such as back / forward are made easier to implement when we have a single store with the full state of our application.

Status is read-only

The only way to change the state is to issue an action indicating that it changed.

This ensures that no part of the application, such as UI events, callbacks, or sockets, directly alters the state of your application, instead of emitting an intention to modify it.
And thanks to the fact that all the modifications are centralized and executed one by one, it is impossible for changes to be stepped on. Finally, since the actions are flat objects, they can be displayed in the console or stored to be re-executed during debugging.

Changes are made through pure functions

To control how the store is modified by the actions, pure reducers are used.

Reducers are pure functions that receive the current state of the application and the action to be performed and return a new state, without directly modifying the current state. We can have a single Reducer in charge of our entire application or if it grows, divide it into multiple functions which we can control in what order they are executed.

Installation process

To install Redux like any library or framework we first need to have Node.js in our system and npm or node package manager.

We run the command below in our terminal.

npm i -S redux

Then we can import the Redux library as a module.

import redux from 'redux';

Internally the Redux library is installing two dependencies:

  • loose-envify to inject environment variables.
  • lodash a collection of utility functions for functional programming.

Basic concepts

Redux is quite easy to learn, although at first glance it may not seem like it, it is even so easy that the library is incredibly small (2kb minified).

Actions

Actions are POJOs (Plain Old JavaScript Objects) with at least one property that indicates the type of action and, if necessary, other properties indicating any other data necessary to carry out our actions. Usually, the format defined in the Flux Standard Action (FSA) is used.

{     
type: 'ADD_TODO',
payload: {
text: 'Learn Redux',
},
}

To send an action to our Store we use the store.dispatch( ) function passing our action as the only parameter.

Actions creators

These are simple functions that may or may not receive parameters and return an action (a POJO), it is a very good idea, to avoid consistency problems, program a function for each type of action and use them instead of assembling our objects by hand.

function addTodo(text) {     
return {
type: 'ADD_TODO',
payload: {
text,
},
};
}

Since they are normally pure functions, they are easy to test. After executing our function, in order to dispatch the action, it is simply to call the dispatch function addTodo(‘Learn Redux’).

Reducers

While actions describe that something happened they do not specify how our application reacts to that something. This is done by the Reducers.

Since the state of our application is a single object, it is a good idea to start thinking about what the most basic form will be before starting to program, as an example we are going to suppose that we make an application of TODOs so that our store will have the following format:

{
todos: [],
}

Now that we define the shape of our store we can start creating reducers. A reducer is a pure function that receives the current state and an action and returns the new state.

(prevState, action) => nextState

Now we are going to program a reducer for our ADD_TODO action:

import { combineReducers } from 'redux';

function todos(state = [], action) {
switch(action.type) {
case 'ADD_TODO':
const copy = Array.from(state);
copy.push(action.payload.text)
return copy;
default:
return state;
}
}

const reducers = combineReducers({
todos,
});

export default reducers;

As seen above, Redux provides us with a function called combineReducers( ) that receives an object with the reducers that we define and combines them. The name that we give to each reducer is used as the property of the store that we create and it is where the state returned by the reducer will be saved.

Store

Finally, we need to create our Store, the store will have four responsibilities:

  • Store the global state of the application.
  • Give access to state using store.getState( )
  • Allow status to update using store.dispatch( )
  • Register listeners using store.subscribe(listener)

It is important to remember that we can only have one store in our Redux applications, when you want to separate the logic of data manipulation you must use the composition of reducers instead of many stores.

To create a store we need a Redux function and the reducer (or the combined reducers) that we are going to use:

import { createStore } from 'redux';
import reducers from './reducers.js';
const initialState = {
todos: [],
};
const store = createStore(reducers, initialState);export default store;

The createStore( ) function simply receives our reducers as the first parameter and our initial state as the second (and optional), in the initial state we can simply send the basic form of our store to send the data received from the server.

Getting our state

Once we have our store created we can access the state it stores with store.getState( ) from any part of our application where we import the store.

import store from './store.js';

console.log(store.getState());

Subscribe to status changes

We can subscribe to the store to find out when it changes and to modify our application accordingly using store.subscribe(callback).

import store from './store.js';

const unsubscribe = store.subscribe(() => {
console.log(store.getState());
unsubscribe();
});

Conclusion

As you can see, Redux is quite simple to start using, and because it is so simple it is possible to combine it with practically any existing framework or library, be it React, Backbone, Angular 1/2, Ember, etc.

--

--