Srikanth Technologies

Using Redux in React

In this blog, we understand how to use Redux to manage state in a React application.

I am keeping everything as simple and straight as possible.

For more detailed information and explanation about Redux, do refer to Official Documentation

Redux is a JavaScript library to manage state. It stores state in a store and makes that available to all Components.

I assume you know React and how to manage state in React using other techniques like lift-state up and Context.

State management is always an important aspect of any React application.

When state(data) is not very large and not many Components need to access it then we can use one of the following:

However, when we have a lot of state and many components need to access different parts of state, then managing state using Redux is a better approach.

What is Redux?

Redux is a JavaScript library for managing application state, using events called actions.

The following are important components of Redux:

Actions

An action is a JavaScript object that specifies type of action to be performed using type property, which is a meaningful string.

Action object can also provide extra data related to action using other properties in action object. These other properties can be named anything, though payload is a common name used.

Reducer

A reducer is a function that receives the current state and an action object. It performs required action on state and returns new state.

This is like an event handler.

All changes to state must be done in reducer.

Store

Store is used to store application state. It is associated with Reducer. We need to associate store with parent component so that all child components can access store and retrieve data. All changes to data in the store are done through Reducers associated with store.

Dispatch

This function of the store is used to dispatch action object to reducer. This is equivalent to raising events and it triggers action.

Sample Application - Counter

Here is a very simple React application that uses Redux to store state.

Create Application

Run the following npx command from command prompt to create a new React application. If you want to use an existing application, that is fine. Just skip this step and follow from next step.

npx create-react-application counter 

Install libraries

We use external libraries – redux, redux-react and @reactjs/toolkit.

We need to install these libraries using following commands.

npm install redux
npm install react-redux 
npm install @reduxjs/toolkit

For the sake of simplicity, I am placing all files in the same folder (i.e. src). Depending on your requirements, you can rearrange these files into different folders. The following are the files related to this application.

Creating Reducer - counterReducer.js

Reducer is a function that performs the specified action on state.

It takes two parameters – state and action. State is current state available in the store. We need to modify state according to action and return new state, which is stored in store by Redux.

Action object has type property that specifies the action to be taken. Additional properties are used to provide extra information about event.

export default function counterReducer(state = {counter : 0}, action) {
    switch (action.type) {
        case "increment":
            return {...state, counter : state.counter + 1}
        case "decrement":
            return { ...state, counter: state.counter - 1 } 
        case "incrementBy":
            return { ...state, counter: state.counter + action.increment} 
        default:
            return state;
    }
}
Our reducer supports three actions – increment, decrement and incrementBy.

Reducer is supposed to change state that it receives based on the action sent and return new state.

In our example, state contains a single property counter, which is set to 0 initially.

When the given action is not supported by reducer then it should return state unchanged.

For action incrementBy, we take increment value from increment property of action object. This is known as payload.

Creating Store – store.js

Store is created using configureStore() function of @reduxjs/toolkit library.

We need to specify the reducer to be associated with store. There may be many reducers associated with a single store.

import { configureStore } from '@reduxjs/toolkit'
import counterReducer from './counterReducer'

export default function getStore() {
        return configureStore(
        {
            reducer : counterReducer
        }
    )
}

Creating Counter component – Counter.js

This component is associated with the current store (specified using <Provider> in index.js) and gets access to state whenever state is changed.

All that is done by using useSelector() hook. We need to provide a selector function to this hook and extract required information – counter property in this case.

Another hook – useDispatch() - is used to get dispatch function, which is used to dispatch an action.

While dispatching an action, we can provide additional information other than type by adding more properties. This is demonstrated using increment property in incrementBy action.

import React from 'react'
import {useDispatch, useSelector } from 'react-redux'

export default function Counter() {
    const counter = useSelector(state => state.counter)  // get counter from state
    const dispatch = useDispatch()
    return (
        <>
            <h1>{counter}</h1>
            <button onClick={() => dispatch({type : 'increment'})}>Increment</button>
            &nbsp;
            <button onClick={() => dispatch({type: 'decrement'})}>Decrement</button>
            &nbsp;
            <button onClick={() => dispatch({type: 'incrementBy', increment : 10})}>Increment By 10</button>
        </>
    )
}

Index.js

This is where we create the store and associate it with Counter component by enclosing it with <Provider>, where store is specified.

All components enclosed by <Provider> can now access the store, receive state and dispatch actions.

import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
 
import getStore from './store'
import Counter from './Counter';
import { Provider } from 'react-redux'

const store = getStore()   // Create store and get it

ReactDOM.render(
  <Provider store={store}>  // Associate store with all child components 
     <Counter />
  </Provider>,
  document.getElementById('root')
);

Sample Run

Run React application and you see the following page.

Click on buttons to see how Counter changes. Click on "Increment By 10" button to see counter incremented by 10.

Keep Learning, Keep Growing

Srikanth Pragada