Skip to main content

Command Palette

Search for a command to run...

Master Modern Redux with ReactJs - 5 Simple Steps to Follow

Updated
6 min read
R

A devoted developer during the day, and a diligent technical writer at night. Writing essential documentation for easy use by developers. Building tools to support both developers and businesses.


One of the best decisions to make or the best approach to follow as a UI developer is in how you manage the state of your application.

Improper state management can lead to “hard-to-manage” code or unnecessary state transfers (known as props drilling in react) between a component and another. These and more are reasons to consider redux implementation in your application. Read here for other redux benefits.

As a popular JavaScript pattern and library for managing states, redux conveniently stores all of the states in a separate place, a store, while providing them globally to your application. In the recent use of redux, the redux toolkit and react-redux is the recommended modern and best practice for implementing redux logic. Read here for more about modern redux.

So, this article guides you through the 5 simple steps to set up and implement modern redux in your React application. You need to know also that redux can be implemented with other UI frameworks.

Prerequisites:

You must have:

Step 1: Set up your React application locally

This step is only if you cloned the React app from the provided GitHub repo, else move to step 2.

In your terminal, run the below command line at the root level of your cloned todo-app. This action installs all of the todo-app start packages.

npm install

Step 2: Install Redux packages

Run the below command line to install the two required packages (redux toolkit and react-redux) for redux configuration and layer binding.

npm @reduxjs/toolkit react-redux

Step 3: Set Up Redux Slice

Create an “app” folder inside the “src” folder located at the root level of your application. Also, create a “todoSlice.js” file inside the “app” folder. Your file setup should look the same as the below snapshot.

file-setup-look

Open the “todoSlice.js” file and import createSlice API from the redux toolkit at the top level of the file. Copy the code below into the file to set up your todoSlice.

Import { createSlice } from ‘@reduxjs/toolkit’;

const getValue = ()=>{
     const localTodoList = window.localStorage.getItem(“todoList”);
     Return localTodoList ? JSON.parse(localTodoList) : window.localStorage.setItem(“todoList”, JSON.stringify([]));
}

const initialValue = {todoList: getValue()}

export const todoSlice = createSlice({
  name: ‘todo’,
  initialState: initialValue,
  reducers: {
     addTodo: (state, action)=>{
         const allTodos = window.localStorage.getItem(“todoList”);
         if(allTodos){
             const allTodosJSON = JSON.parse(allTodos)
             const newTodosJSON = [ …allTodosJSON, action.payload ]
             window.localStorage.setItem(“todoList”, JSON.stringify(newTodosJSON);
             state.todoList = newTodosJSON;
         } else {
             window.localStorage.setItem(“todoList”, JSON.stringify([{ …action.payload }]))
         }
     },
     deleteTodo: (state, action)=>{
         const allTodos = window.localStorage.getItem(“todoList”);
         if(allTodos){
             const allTodosJSON = JSON.parse(allTodos);
             const filteredTodos = allTodosJSON.filter((todo)=>todo.id !== action.payload);
             state.todoList = filteredTodos
         }
      }
     }
});

export const { addTodo, deleteTodo } = todoSlice.actions

export default todoSlice.reducer

Note: A slice comprises a slice name, an initial state value, and one or more reducer functions to define how the state would be updated.

Step 4: Set Up Redux Store

In the “app” folder you initially created, create a “store.js” file inside the “app” folder. Your file setup should look the same as the below snapshot.

file-setup-look

Open the “store.js” and import configureStore API from the redux toolkit, and todoSlice API from the todoSlice at the top level of your “store.js” file. Copy and paste the code below.

import { configureStore } from '@reduxjs/toolkit';
import todoSlice from ‘./todoSlice’

export default configureStore({
       Reducer: { todo: todoSlice }
   })

The configureStore API sets up a redux store with the right defaults - it calls applyMiddleware with the default list of middlewares and calls composeWithDevTools to set up the redux dev tools extensions.

At the entry file of your application ( main.jsx ), import both the Provider API (from react-redux) and “store” (from the store.js file) at the top level of your “main.jsx” file.

Also, wrap the entry point with the Provider API and pass it a store prop with the “store” that was imported from store.js file. See below for a guide.

import React from ‘react’;
import ReactDOM from ‘react-dom/client’;
import App from ‘./App.jsx’;
import ‘./styles/index.module.css’;
import { Provider } from ‘react-redux’;
import store from ‘./app/store’;

ReactDOM.createRoot(document.getElementById(“root”)).render(
  <React.StrictMode>
    <Provider store={ store } >
      <App />
    </Provider>
  </React.StrictMode>
);

Now, you’re ready to access the redux store anywhere inside your application.

Step 5: Access and Use Redux Store

Import any of the react-redux hooks (useDispatch and useSelector) at the top level in your app.

React-redux serves as a binding layer that allows your React applications to interact with the redux store effectively.

useDispatch - It takes in any of your reducer actions (with payload) to update the app’s state inside the redux store.

import { useContext, useState } from ‘react’;
import { FaTimes } from ‘react-icons/fa’;
import styles from ‘../styles/App.module.css’;
import { LoadFormContext } from ‘./ContentLayoutComponent’;

import { useDispatch } from ‘react-redux’;
import { addTodo } from ‘../app/todoSlice’;


const FormComponent = ()=>{
   const dispatch = useDispatch();

   const { setLoadForm } = useContext(LoadFormContext)
   const [activity, setActivity] = useState(“”);

   const HandleSubmit = (e)=>{
       e.preventDefault();
       if(!activity){
           toast.error(“Fill required fields”);
       } else {
           dispatch(
              addTodo( { activity } )
           );
           setLoadForm(false);
      }
   };


  //
  return (
     <div className={styles.form_wrapper}>
      <div className={styles.form_container}>
       <form className={styles.form_body} onSubmit={(e)=>HandleSubmit(e)}>

        //This is the body of the form to be rendered..//

       </form>
      </div>
     </div>
  );
};

export default FormComponent;

useSelector - It takes in a callback function as an argument that returns the part of the state that you want to have access to.

import { useDispatch, useSelector } from ‘react-redux’;
import { FormContext } from ‘./ContentLayoutComponent’;
import { AirFillEdit, AiFillDelete } from ‘react-icons/ai;
import styles from ‘../styles/App.module.css’;
import { useContext } from ‘react’;
import { deleteTodo } from ‘../app/todoSlice’;


const ItemComponent = ()=>{
   const allTodoItems = useSelector((state)=> state.todo.todoList);
   const dispatch = useDispatch();
   const { setLoadForm, setAction, setTodo } = useContext(FormContext);

   const HandleEdit = ()=>{
      setTodo(todo);
      setAction(“Update”);
      setLoadForm(true);  
   }

   const HandleDelete = (todo_id)=>{
      dispatch(deleteTodo(todo_id))
   }


   return (
    <>
     <div className={styles.item_wrapper}>
      {allTodoItems && allTodoItems.length > 0 ? (
       <div className={styles.item_container}>
        {allTodoItems.map((todo)=>
         <div key={todo.id} className={styles.item_card}>
          <h2 className={styles.item_card_title}>
           {todo.activity}
          </h2>
          <div className={styles.item_card_icon}>
           <div onClick={()=>HandleEdit()}>
            <AiFillEdit size={“1.9rem”} color=”rgb(204, 204, 204)” />
           </div>
           <div onClick={()=>HandleDelete()}>
            <AiFillDelete size={“1.9rem”} color=”rgb(204, 204, 204)” />
           </div>
          </div>
         </div> )}
       </div> ) : (
       <div className={styles.no_todo_container}>
        <p className={styles.no_todo_item}>No Todo Added
       </div>
      )
     </div>
    </>
   )
}

Conclusion

Whether as a newbie or a seasoned expert in application frontend development, this article is a great catch and guides you on the simple steps to set up and implement modern redux in your application. So, you do not necessarily set up everything manually.

If you have followed this article with the provided example practice, then, you’re confident to write modern redux logic in your application. And you can clone the completed application GitHub repository here.

If this was helpful, leave a reaction to the article.

And, expect my next article on simplified steps in implementing Redux Toolkit Query (RTK) Query when interacting with APIs.

More from this blog

Essential.Dev

2 posts

A full-stack software developer during the day, and a technical writer at night. I love sharing documented step-by-step simplest approaches to doing this tech thing.

Master Modern Redux with ReactJs - 5 Simple Steps to Follow