Open In App

How to Integrate Redux with React Components ?

Last Updated : 19 Apr, 2024
Improve
Improve
Like Article
Like
Save
Share
Report

Redux is an open-source JavaScript library for managing and centralizing application state. It helps you to write applications that behave consistently and are easy to test and run in different environments. It can also be understood as the predictable state container for the JavaScript app. It is most commonly used with JavaScript libraries like React or Angular.

What are the principles that Redux works on?

There are three principles that redux works on:

  • Single source of truth: The entire state of the application is stored inside Redux store in a single JavaScript object making it easier for the developer to manage and access states anytime and anywhere in the application.
  • Read-Only State: This principle states that the states can not be modified directly. To modify the redux state, a developer must dispatch the type of action to be performed in the form of the plain JavaScript object called Actions. These actions will be later handled by a special function called reducers which updates the state.
  • Pure functions make the change: Reducers are the pure functions meaning that they will always produce the same output for a desired input. Not having any side effects makes it easier to test Reducers.

Steps to integrate Redux with React Components

Step 1: Install the redux packages

The first step is to install all the required libraries. You can use the blow command to install them.

npm i redux react-redux @reduxjs/toolkit

Step 2: Create the actions file

Now create a folder named redux in your src folder. Then inside that redux folder, create a folder named tasks. Inside that tasks folder create a file name action.js.

Step 3: Create the Reducer file

Now navigate to redux folder and create a file named taskReducer.js. This is the main file where your code manipulation and state changes will be done.

Step 4: Create a store file

Inside the folder named redux, create a file named store.js.

Step 5: Add the useDispatch hook in your react component

Now you can use useDispatch hook to access the dispatch method.

Project Structure:

Screenshot-2024-04-10-152359

Folder structure for adding redux

Example: The below code example implements the integration of redux with react components.

JavaScript
// TodoList.js
import React from "react";
import { connect } from "react-redux";
import { toggleTodo } from "./redux/tasks/action";

const TodoList = ({ todos, toggleTodo }) => {
    return (
        <ul>
            {todos.map((todo) => (
                <li
                    key={todo.id}
                    onClick={() => toggleTodo(todo.id)}
                    style={{
                        textDecoration: todo.completed ?
                            "line-through" : "none",
                        cursor: "pointer",
                    }}
                >
                    {todo.text}
                </li>
            ))}
        </ul>
    );
};

const mapStateToProps = (state) => ({
    todos: state.todos,
});

export default connect(mapStateToProps,
    { toggleTodo })(TodoList);
JavaScript
//index.js
import React from "react";
import ReactDOM from "react-dom/client";
import App from "./App";
import { Provider } from "react-redux";
import store from "./redux/store";

const root = ReactDOM.createRoot
    (document.getElementById("root"));
root.render(
    <React.StrictMode>
        <Provider store={store}>
            <App />
        </Provider>
    </React.StrictMode>
);
JavaScript
//App.js
import React from "react";
import TodoList from "./TodoList";
import AddTodo from "./AddTodo";

function App() {
  return (
    <div className="App">
      <h1>Todo App</h1>
      <AddTodo />
      <TodoList />
    </div>
  );
}

export default App;
JavaScript
//AddTodo.js
import React, { useState } from "react";
import { connect } from "react-redux";
import { addTodo } from "./redux/tasks/action";

const AddTodo = ({ addTodo }) => {
    const [text, setText] = useState("");

    const handleSubmit = (e) => {
        e.preventDefault();
        if (!text.trim()) return;
        addTodo(text);
        setText("");
    };

    return (
        <form onSubmit={handleSubmit}>
            <input
                type="text"
                value={text}
                onChange={(e) => 
                        setText(e.target.value)}
            />
            <button type="submit">
                Add Todo
            </button>
        </form>
    );
};

export default 
    connect(null, { addTodo })(AddTodo);
JavaScript
//taskReducers.js
import { ADD_TODO, TOGGLE_TODO } from
    "./tasks/action";

const initialState = {
    todos: [],
};

const rootReducer =
    (state = initialState, action) => {
        switch (action.type) {
            case ADD_TODO:
                return {
                    ...state,
                    todos: [
                        ...state.todos,
                        {
                            id: state.todos.length + 1,
                            text: action.payload,
                            completed: false,
                        },
                    ],
                };
            case TOGGLE_TODO:
                return {
                    ...state,
                    todos: state.todos.map((todo) =>
                        todo.id === action.payload
                            ? 
                            { 
                                ...todo, 
                                completed: !todo.completed 
                            }
                            : todo
                    ),
                };
            default:
                return state;
        }
    };

export default rootReducer;
JavaScript
//store.js
import { configureStore } 
    from "@reduxjs/toolkit";
import taskReducer from "./taskReducers";
const store = 
    configureStore({ reducer: taskReducer });
export default store;
JavaScript
//action.js
export const ADD_TODO = "ADD_TODO";
export const TOGGLE_TODO = "TOGGLE_TODO";

export const addTodo = (text) => ({
    type: ADD_TODO,
    payload: text,
});

export const toggleTodo = (id) => ({
    type: TOGGLE_TODO,
    payload: id,
});

Output:

fosiGIF



Like Article
Suggest improvement
Previous
Next
Share your thoughts in the comments

Similar Reads