What is Redux?

Redux is a datastore for React and javascript applications to handle the applications’ states. It is also called a predictable state container for the applications. It is well-known that the complexity of code in an application increases with its growth, and it becomes difficult for the developers to maintain the data flow while keeping the code organized. Therefore, the open-source software community developers introduced this library to manage the state using the store, a global object. Moreover, it helps develop applications that run in various environments and still behave consistently.

Redux Dataflow in React to Handle Application’s Consistent State

Working Principle of Redux

Redux works on the principle that all application’s data should flow only in one direction to help maintain consistency. Moreover, the application should store the data as a single entity or source of truth, and the users can update it by sending requests to the redux store. Due to its simple design principle and relatively more straightforward implementation, the developers prefer it to manage the application state and make testing and debugging more manageable.

Following are the concepts/terms that the users must familiarize themselves with before starting the tutorial:

1.   States:

The application’s states are read-only, and there is no way to modify them directly. The users can change them only by sending the action to the store.

2.   Actions:

These are the simple objects in the application to define the intention of the user. For instance, the reducer function needs to understand the intention to update the state accordingly.

3.   Store:

It is a single object in the application that contains all data selection fields. The users can update the data by sending an action containing the information about the data to the store.

4.   Reducers:

These are the functions that take the current state and action as their parameter. They then interpret the actions sent by the users and update the data accordingly. Also, instead of changing the existing state, these functions apply action to the data and return the new state. Moreover, the users can only modify states by sending actions to the reducers, making them centralized and anticipated.

Data flow in the Redux App

Redux only allows the application’s data to flow in one direction. i.e., unidirectional data flow, due to which the users can easily visualize the data flow, making it easier for them to add new functionality in the application and predict its state at any time.

Following is the simplistic data-flow diagram that Redux follows for the applications:

Data Flow

Explanation

  1. When the user interacts with the application’s user interface, it will send an action to the backend.
  2. The backend will then call the reducer function with the action and the current state to return a new state.
  3. The store will notify the view after the callback function’s execution ends.
  4. The view will render the components based on the new state.

Installation Process

  • Before installing Redux, the users must have node js installed on their systems. The users can visit this link https://nodejs.org/ to install its packages.
  • The users can verify the success of node package installation by pasting the following command in their terminal.
npm -v
  • This command will return the npm package’s version in case of a successful installation.
  • Please note that npm is a package manager for node js to install or uninstall various node packages and resolve the dependencies.
  • The users can then install the redux by running the following command in the terminal.
npm install --save redux react-redux
  • This command will install two packages. One is the redux package itself, and the second is the redux dependencies to develop reactjs applications with redux.
  • The final step is to install the redux development tools by pasting the following command in the terminal. The users can choose to install the Redux Devtools extension for their browsers if they do not want to integrate the development tools with their react project.
npm install --save-dev redux-devtools

Developing an essential app to demonstrate state handling

Below is an example to help users develop apps with react and redux by building on top of it.

  • After following the above installation steps, the users need to connect the Redux to their react project. However, redux cannot work without a provider. Therefore, the user must wrap the application’s components with it in the index.js or main.js file. This component wrapping ensures that the redux store is available to all the tree’s children.
  • The users need to import the provider, create store and reducer components and functions for the redux in the index.js file. Below is the sample code for the simple index file.
//importing essential modules and components
import React from 'react'
import { render } from 'react-dom'
import { Provider } from 'react-redux'
import { createStore } from 'redux';
import reducer from '../src/reducer/index'
import App from '../src/App'
import './index.css';

//creating the store
const store = createStore(
   reducer,
   window.__REDUX_DEVTOOLS_EXTENSION__ &&
   window.__REDUX_DEVTOOLS_EXTENSION__()
)

//rendering the react components
render(
   <Provider store = {store}>
      <App />
   </Provider>, document.getElementById('root')
)
  • This index file is responsible for rendering the react components and creating the store for storing the data fields. The users can modify the store by including their application’s data fields, such as the JSON object of a zoo containing the data fields for all the animals.
  • In this tutorial, the users will be incrementing or decrementing a counter. Therefore, a separate file should be responsible for rendering the counter containers. Below is the code for the app.js file, which will be react’s root component.
import React, { Component } from 'react';
import './App.css';
import Counter from '../src/container/appContainer';

class App extends Component {
   render() {
      return (
         <div className = "App">
            <header className = "App-header">
               <Counter/>
            </header>
         </div>
      );
   }
}
export default App;
  • The users need to create a container file that will provide the react component with the redux’s state. Below is the code for the container file named counterCountainer.js
/container/counterContainer.js
import { connect } from 'react-redux'
import Counter from '../component/counter'
import { increment, decrement, reset } from '../actions';

const mapStateToProps = (state) => {
   return {
      counter: state
   };
};

const mapDispatchToProps = (dispatch) => {
   return {
      increment: () => dispatch(increment()),
      decrement: () => dispatch(decrement()),
      reset: () => dispatch(reset())
   };
};
export default connect(mapStateToProps, mapDispatchToProps)(Counter);
  • The users then need to create the react components, which they can use to change the application’s state. For instance, buttons or icons to increment or decrement the counter state. Below is the code for creating the components. The users can change or customize the components to their liking.
/component/counter.js
import React, { Component } from 'react';
class Counter extends Component {
   render() {
      const {counter,increment,decrement,reset} = this.props;
      return (
         <div className = "App">
            <div>{counter}</div>
            <div>
               <button onClick = {increment}>INCREMENT BY 1</button>
            </div>
            <div>
               <button onClick = {decrement}>DECREMENT BY 1</button>
            </div>
            <button onClick = {reset}>RESET</button>
         </div>
      );
   }
}
export default Counter;
  • The users then need to create the react components, which they can use to change the application’s state. For instance, buttons or icons to increment or decrement the counter state. Below is the code for creating the components. The users can change or customize the components to their liking.
/actions/index.js
export function increment() {
   return {
      type: 'INCREMENT'
   }
}
export function decrement() {
   return {
      type: 'DECREMENT'
   }
}
export function reset() {
   return { type: 'RESET' }
}
  • Finally, the users need to write the reducer file for the application, which will change the application’s state whenever a user performs an action. The reducer function takes state and action as its parameter and updates the state, as described in the workflow of redux.
reducer/index.js
const reducer = (state = 0, action) => {
   switch (action.type) {
      case 'INCREMENT': return state + 1
      case 'DECREMENT': return state - 1
      case 'RESET' : return 0 default: return state
   }
}
export default reducer;
  • Now, the app is ready, and the users can run it to view buttons on their screens which they can use to reset the counter or increment and decrement the count by 1.

Redux is a popular yet essential library to help create applications with unidirectional data flow, which makes development more manageable and saves the app from data conflict. Therefore, it is beneficial in the scenarios where the applications depend on a single source of data for maintaining their code and data flow.