Mastering Redux in React: The Complete State Management Guide

  • react-js
  • 90 Views
  • 6 Min Read
  • 8 May 2024

Hi, Coders! If you're looking to make your React apps better by managing state effectively, you're in the right spot.

 

Discover Redux in this article: its meaning, advantages, workings, best applications, and a project to ensure you grasp React Redux fully.

 

Let's dive in!

 

  1. What is Redux in React?
  2. Redux Principles: Optimizing State Management
  3. Why should we use Redux?
  4. How Does Redux Work?
  5. How to Use Redux in Our Projects?
  6. When should we use Redux?
  7. When should I avoid using Redux, and what is the alternative option?
  8. Best Practices for Redux

 

 

What is Redux in React?

 
Redux is a powerful state management library that helps predictably manage application state. We can use it with React, Angular, Vue, and vanilla JavaScript, making it indifferent to the UI library preference. Because Redux is just a state management library, it doesn't matter what library we use to build user interfaces. Many developers prefer using Redux when working with large projects in React.
 
Redux also has reducers, which are like traffic signals for your app. When changes occur, these 'traffic signals' step in to direct the next actions, ensuring your app knows how to adapt and stay current.
 
 

Redux Principles: Optimizing State Management

 
In Redux, there are three main principles:
 
  • A Single Source of Truth:
  • The state is read-only:
  • Changes are made with pure functions:
 
A Single Source of Truth: All the data for your app is stored in one central place. This helps you easily handle and get to the state of your whole app.
 
Imagine your app is like a book, and the store is the table of contents. Just like the table of contents lists all the chapters in one place, the Redux store holds all the data for your app in one location.
 
The state is read-only: You can't directly change the data in the store. When you want to change something in your app, you have to send a message called "action." It's like asking for a specific change to happen. For example, you might send an action to add or delete something from the app's data.
 
Changes are Made with pure functions: Redux uses pure functions called reducers to determine how the state should change in response to actions. Reducers take the previous state and an action and return the new state.
 
Think of reducers as chefs in a kitchen. When you give them ingredients (previous state) and a recipe (action), they prepare a new dish (new state) without changing the original ingredients or the recipe. This ensures that each time you follow the same recipe with the same ingredients, you'll get the same result.
 
 

Why should we use Redux?

 
When you use Redux with React, you don't have to move around the app's state. Redux also helps you figure out which actions are changing the app. Furthermore, it's simple to keep everything organized, detect and fix issues, and test the app.
 
Imagine you're creating a large React application with many parts. As it grows, keeping track of the data flow between components becomes challenging. This is where integrating Redux becomes crucial for easier management.
 
 

How Does Redux Work? 

 
How React Redux work
 
Redux manages the app state in a central store. When events like button clicks occur, Redux dispatches actions, described as plain JavaScript objects. Reducers update the state based on these actions. Components access the state from the Redux store, simplifying state management.
 
It's time to get hands-on with building a simple to-do app to see how Redux can be implemented in our projects.
 
 

How to Use the Redux in our Projects?

 
Let's build a basic to-do app together that will show how we can properly include Redux into React, step-by-step.
 
  • Step 1: Create a React App
  • Step 2: Install dependencies like Redux, React-Redux and Redux-toolkit 
  • Step 3: Define Reducers
  • Step 4: Create Your Redux Store
  • Step 5: Connect Redux to Your React App
  • Step 6: Create Todo List Components and Dispatch Actions
  • Step 7: Finally, import the Todo component in the App.js

 

Step 1: Create a React App

 
First, create a new React application using Create React App:
 
npx create-react-app todo-list-redux
 

Step 2: Install dependencies like Redux, React-Redux and Redux-toolkit 

 
You can install all these dependencies with the following command.
 
npm install redux react-redux
npm i @reduxjs/toolkit
 

Step 3: Define Reducers

 
Create a folder named "reducers" in your src directory. Within this folder, define your reducers. For the todo list, we'll have a reducer to manage the todo items:
 
// src/reducers/todoReducer.js

const initialState = {
    todos: []
};

export const todoReducer = (state = initialState, action) => {
    if (action.type === 'ADD_TODO') {
        return {
            ...state,
            todos: [...state.todos, action.payload]
        };
    } else if (action.type === 'TOGGLE_TODO') {
        return {
            ...state,
            todos: state.todos.map(todo =>
                todo.id === action.payload ? { ...todo, completed: !todo.completed } : todo
            )
        };
    } else if (action.type === 'DELETE_TODO') {
        return {
            ...state,
            todos: state.todos.filter(todo => todo.id !== action.payload)
        };
    } else {
        return state;
    }
};

export default todoReducer;
 
In this code, we have created a TodoReducer function to manage the state of todo items in the Redux store. It handles tasks like adding, toggling, and deleting todos based on the action type given. As a result of this function, all associated tasks within the app are organized and efficient.
 

Step 4: Create Your Redux Store

 
In your src directory, create a store.js file to configure your Redux store:
 
// src/store/store.js

import { configureStore } from '@reduxjs/toolkit';
import todoReducer from '../reducers/todoReducer';

const store = configureStore({
    reducer: todoReducer,
});

export default store;
 
In this code snippet, we create a Redux store using the configureStore function from the Redux Toolkit library. The store is set up with the todoReducer, which handles the state of to-do items in the app. After setting it up, we export the store so it can be used everywhere in the app.
 

Step 5: Connect Redux to Your React App

 
Wrap your entire application with the <Provider> component from React-Redux and pass your Redux store as a prop:
 
// index.js

import React from 'react';
import ReactDOM from 'react-dom/client';
import { Provider } from 'react-redux';
import App from './App';
import store from './store/store';

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
    <Provider store={store} >
        <App />
    </Provider>
);
 
In this code snippet, we import necessary modules such as React, ReactDOM, Provider, App, and store. We create a root element using ReactDOM.createRoot and specify the target element with document.getElementById('root'). Then, we use root.render to render the main App component wrapped with the Provider component. The Provider component ensures that the Redux store is accessible to all components in the React application. 
 

Step 6: Create Todo List Components and Dispatch Actions

 
Create your to-do list components and use Redux to manage the state. Here's a simple example of Todo.jsx:
 
// src/components/Todo.jsx

import React, { useState } from 'react';
import { nanoid } from '@reduxjs/toolkit'
import { useSelector, useDispatch } from 'react-redux';
import './todo.css'

const Todo = () => {
    const [inputValue, setInputValue] = useState('');
    const todos = useSelector(state => state.todos);
    const dispatch = useDispatch();

    const handleAddTodo = () => {
        dispatch({ type: 'ADD_TODO', payload: { id: nanoid(), text: inputValue, completed: false } });
        setInputValue('');
    };

    const handleToggleTodo = id => {
        dispatch({ type: 'TOGGLE_TODO', payload: id });
    };

    const handleDeleteTodo = id => {
        dispatch({ type: 'DELETE_TODO', payload: id });
    };

    return (
        <div>
            <input type="text" value={inputValue} onChange={e => setInputValue(e.target.value)} />
            <button onClick={handleAddTodo}>Add Todo</button>
            <ul>
                {todos.map(todo => (
                    <li key={todo.id}>
                        <span style={{ textDecoration: todo.completed ? 'line-through' : 'none' }}>{todo.text}</span>
                        <button onClick={() => handleToggleTodo(todo.id)}>{todo.completed ? 'Undo' : 'Complete'}</button>
                        <button onClick={() => handleDeleteTodo(todo.id)}>Delete</button>
                    </li>
                ))}
            </ul>
        </div>
    );
};

export default Todo;
 
In this code snippet, we have a React functional component named Todo, which manages a todo list. It utilizes useState hook to handle input values and the useSelector hook to access todos from the Redux store. Dispatching actions are done through the useDispatch hook to add, toggle, and delete todos. The component renders an input field for adding todos, displays existing todos, and provides buttons for toggling the completion status and deleting todos.
 

Step 7: Finally, import the Todo component in the App.js

 
Import the TodoList component into your App.js file and render it within your application. This will display the todo list and allow users to interact with it.
 
// App.js

import React from "react";
import Todo from "./components/Todo";

const App = () => {
    return (
        <>
            <Todo />
        </>
    );
};

export default App;
 
In this code, we have the main component of our React application, App.js. The App component returns the Todo component, rendering it the main content of the application. This sets up the structure for our todo list application, where the Todo component will handle the functionality for managing and displaying todo items.
 
React Redux Todo App
 
Congratulations! We did it! We've gone through all the important steps in a simple and easy-to-understand way. Now, you know how to manage your app's state effectively using Redux.
 
 

When should we use Redux?

 
Listed below are some opinions about how Redux can be used effectively to manage complex states across React applications.
 
Shared State: You need to share state across multiple components of your application without passing props through every level of the component tree.
 
Predictable State Management: You require a predictable state container with strict rules to ensure consistency and maintainability.
 
Large Applications: Your application's state is large and complex, making it difficult to manage with just React's built-in state management.
 
Time Travel Debugging: You want the ability to debug and inspect previous states and actions, which Redux enables through its dev tools.
 
Middleware: You need to perform asynchronous operations, such as fetching data from an API, and handle side effects efficiently.
 
Server-Side Rendering: You're building a server-rendered application and need a way to serialize and hydrate your Redux store on the server and the client.
 
 

When should I avoid using Redux, and what is the alternative option?

 
If your project is small, consider using the Context API for state management. If your project is even smaller, just passing data via props might work fine. In these cases, it's better to steer clear of Redux because it can make things more complicated. Instead, you can consider simpler options like the Context API or prop drilling in a small project.
 
However, if your project gets bigger and more complex, Redux might be a better choice for managing state efficiently.
 

Best Practices for Redux

 
Single Source of Truth: Maintain a single Redux store for the application state.
 
Immutability: Ensure state changes are immutable to prevent unintended side effects.
 
Separation of Concerns: Organize code into actions, reducers, and selectors for modularity.
 
Normalized State: Structure state shape to be flat and normalized.
 
Selective Containerization: Connect only the necessary components to Redux.
 
Middleware Usage: Use middleware for asynchronous operations, keeping reducers pure.
 
Memoization: Utilize memoization for optimized rendering performance.
 
Testing: Write unit tests to validate Redux logic.
 
DevTools Integration: Utilize Redux DevTools for debugging.
 
Documentation: Document the code thoroughly for future reference.
 
 

Conclusion

 
We have covered almost everything about react-redux in this article by creating projects. Remember that Redux makes it easy to properly manage data in our large projects. By following best practices and knowing when to use Redux (and when to consider other options), you will then be well-equipped to take your projects to the next level. For example, in large projects, using React Redux is a good option, and in small projects, using the Context API is a good option.
 
If you have any questions regarding this article or any other web development, then you can ask them in the question box given below, and you will get the answer as soon as possible.

Didn't find your answer? Add your question.

Share

Comments (0)

No comments yet. Be the first to comment!

About Author

Username

Poojan Joshi ( poojanjoshi )

Full Stack JavaScript Developer

Joined On 12 Apr 2024

More from Poojan Joshi

Top 60 Eye-Catching Button Designs Users Can’t Wait to Click - With Source Code

ui-ux

11 Oct 2024

Discover 60 eye-catching button designs with source code, crafted with HTML and CSS to enh....

How to Check Website Speed: Key Metrics, Tools, and Optimization Tips

web-development

21 Sep 2024

Learn how to test your website speed, key metrics to track, top tools to use, and expert o....

Everything About Debouncing Function in JavaScript: Comprehensive Guide

javascript

13 Aug 2024

Learn everything about the debouncing function such as what it is, why and where to use it....

How to Create Advanced Search Bar with Suggestions in React: A Step-by-Step Guide

react-js

2 Aug 2024

Learn to build an advanced React search bar with suggestions, highlighted text, efficient ....

How to Create a Full-Featured Todo List App Using ReactJS

react-js

19 Jul 2024

Learn how to build a powerful Todo List App using ReactJS. A step-by-step guide covering d....

How to Create a Full-Featured Todo List App Using HTML, CSS, and JavaScript

javascript

16 Jul 2024

Learn to build a feature-rich to-do list with HTML, CSS, and JavaScript. Perfect for inter....

Popular Posts from Code Mafias

10 Fun Websites for Stress Relief and Relaxation During Coding Breaks

programming

11 Nov 2024

Top 10 fun websites for coders to relax during breaks. Recharge with interactive games, ar....

Mastering HTML: Top 12 Unique HTML Tags with Examples

html

4 May 2024

Through this article, learn those essential HTML tags that many developers do not know abo....

Top 60 Eye-Catching Button Designs Users Can’t Wait to Click - With Source Code

ui-ux

11 Oct 2024

Discover 60 eye-catching button designs with source code, crafted with HTML and CSS to enh....

How to Upload Code to GitHub: Quick Steps and Detailed Instructions for Beginners

github

16 Sep 2024

In order to upload (push) your project to GitHub, it involves multiple steps that need to ....

How to install MongoDB on windows in 2024

mongodb

2 May 2024

MongoDB is a Database Management System based on NoSQL (Not Only SQL) and utilizes JSON-li....

How to Implement Undo Functionality for Deleting Items in Your React App

react-js

28 Sep 2024

Learn how to implement undo functionality for deleting items in React. Follow a step-by-st....