How to use Redux for state management in React App

javinpaul - May 17 '22 - - Dev Community

Managing state efficiently is very important in a react application. A React application depends on its state. React provides in-built support to manage the state but as the application grows, this in-built support becomes inefficient.

So to manage the state of a large and complex react application, we have to use third-party state management libraries. Redux is by far the most popular state management library. It is heavily used with react and if you are planning to work in a real-time react project, you will encounter redux.

It is always complicated for beginners to understand and implement redux. It is a complex library. But it is essential to understand redux properly because its implementation is not easy either. In this article, we will discuss more redux.

What is Redux?

As mentioned earlier, Redux is a state management library for React. In simple words, it is a store that stores the global state of the application.

React provides in-built support for managing the state of a component. It is okay to use the in-built support if the application is small. But with larger and complicated applications that have several components and state is required to be shared among them, we need something powerful like redux.

Flow of redux

To understand the working of redux, we need to understand the redux flow. Let's understand the redux flow step by step.

Store

The state of the entire application resides at one place and that place is called Store. If you are familiar with React, then definitely know what state is.

The state controls the behavior of react components. The store provides three powerful methods that are very useful while working with the state. These methods are:

  • dispatch(action)
  • getState()
  • subscribe(listener)

The dispatch method is used to dispatch actions (We will discuss actions later) while the getState() method gives us access to the global state of the application. The subscribe method registers listeners. The first two methods are more used in the application because dispatching actions and accessing the state are required frequently.

User-interface

The user interface is not related to redux but it is where a change takes place. The state of the application defines the UI.

Action

From the UI, actions are dispatched using the dispatch method. Now, the actions define the change.

An action is a plain JavaScript object. It has one mandatory property called "type". This type property has information regarding the change. Moreover, an action can also have a "payload" property to hold data.

Reducer

A reducer is responsible for changing the state according to the dispatched action. The action will contain its type and optional payload and it is the reducer that defines how the state is going to change.

Let's understand the working of redux with the help of a simple example.

To install redux, use the following command.

npm install redux --save
Enter fullscreen mode Exit fullscreen mode

Now, we will create a very basic react + redux application to understand the basic concepts. Observe the following code.

import "./styles.css";

import Button from "./Button";

import Display from "./Display";

const App = () => {

  return (

    <div className="App">

      <Button />

      <Display />

    </div>

  );

};

export default App;
Enter fullscreen mode Exit fullscreen mode

The UI looks like the following:

What is redux and how to use it? Example Tutorial

There are two components - Button and Display. Whenever one of the buttons is clicked, the value in the Display components changes. We will create a global state for this to work.

Observe the reducer.

const reducer = (state, action) => {

  switch (action.type) {

    case "INCREMENT":

      return {

        ...state,

        count: state.count + 1

      };

    case "DECREMENT":

      return {

        ...state,

        count: state.count - 1

      };

    default:

      return state;

  }

};

export default reducer;
Enter fullscreen mode Exit fullscreen mode

The reducer has two parameters - state and action. We have to use the switch loop for iterating over the action and according to the type, the state is updated. Remember, the reducer should only calculate the new state without modifying the already existing state.

Next, observe the store.

import { createStore } from "redux";

import reducer from "./reducer";

const initialState = { count: 0 };

const store = createStore(reducer, initialState);

export default store;
Enter fullscreen mode Exit fullscreen mode

To create a store, we have to use the "createStore" method. The first argument of this method is the reducer and the second is the initial state. In our case, the initial state is "count".

Now, we are ready to dispatch actions.

import { useDispatch } from "react-redux";

const Button = () => {

  const dispatch = useDispatch();

  return (

    <div>

      <button

        onClick={() => {

          dispatch({ type: "INCREMENT" });

        }}

      >

        Increment

      </button>

      &nbsp;

      <button

        onClick={() => {

          dispatch({ type: "DECREMENT" });

        }}

      >

        Decrement

      </button>

    </div>
Enter fullscreen mode Exit fullscreen mode

To dispatch an action, we have the dispatch method. But in the Button component, we will use the "useDispatch" hook for dispatching actions.

const dispatch = useDispatch();
Enter fullscreen mode Exit fullscreen mode

We are directly providing the actions inside the onClick handler like this.

onClick={() => {

  dispatch({ type: "INCREMENT" });

}}
Enter fullscreen mode Exit fullscreen mode

Remember we have to provide the type while dispatching an action.

Now, when the button is clicked, an action is dispatched and according to its type, the reducer will do its work. In the end, the state will be updated in the store.

Now, we have to access the state. The best way to access the state is by using yet another hook called useSelector.

import { useSelector } from "react-redux";

const Display = () => {

  const count = useSelector((state) => state.count);

  return <h2> {count} </h2>;

};

export default Display;
Enter fullscreen mode Exit fullscreen mode

So now, the store has the initial state (count = 0). When the action is dispatched from the Button component, the reducer updates the state according to the type of action. Then, we can access the state wherever we want.

Wrapping it up

You may find redux complicated in the starting but once you understand the redux flow, you can implement redux easily. The main parts of redux are store, action, and reducer. You have to understand their working and then with the help of react hooks, you can implement redux easily in your application.

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .