React Redux in one shot while building a Project
Tags: ai, react, redux, webdev
Published: 2023-06-28 07:21:48

🚀 React is extremely powerful when it comes to dynamic websites because It gives us the functionality of using reusable components in other components, virtual dom and props passing to the different components.

🤕 But when your project grows, It becomes a headache when you pass props under so many levels in your component tree of react

![React Redux Meme](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/50o8w9a2fk4634nplggh.png)

😂 No, I am just kidding. React Redux is very easy to learn. 

**Note:- ** You can also find the [YouTube video](https://youtu.be/k8LnR1LIg4Y) here for better understanding. Drop a subscribe and like for support guys ❤️

## 📌 Let's Start

So, React Redux is a state management or a global store that you provide to your components in your react component tree. And so, other components can access it.

Don't worry we'll see an example of using React Redux while building an App which is responsible for:-

- User to sign up and login (users are stored in the DB)
- User to add todo tasks and then store to the DB

⚡️ So, when user logs in to our app then his/her todo app home looks like this:- 

![Login Page](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1ppodgfp8blwf3ls8zgu.png)

and the homepage of the app looks like this:- 

![Homepage](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7vrrk35bpiq3ow0gtjr1.png)

⚡️ Now, what we want to do in this todo app is to pass the username, that someone entered while logging in, to the homepage component of our todo app. So, that when user clicks on save tasks, he/she can save tasks on the Database specific to his/her username only.


## 🚀 React Redux

But before explaining how to do that, Let's see what React Redux is and how it works.

✨ Let suppose there is no react redux and someone want to buy an item from a e-commerce store. So, the properties that we will pass from login to the different components will be like:- 

![React Redux Props Passing](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/68igwumvsywhtl1iul13.png)

😩 Here we can see that with increase in the component tree level the prop passing or prop drilling will be much more.

So, can we make a global kind of state management store which can store all the states of the components or any other variables. So that others can change the state or fetch the latest state

![React Redux Store](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/a23c1wppd4e1dvdkufcz.png)

Here we can see now login component can dispatch events or payload that can be stored in the redux store and other components can fetch using selectors.

## 💡 Reducers, Dispatchers and Selectors

✨ So, in redux context we have reducers/slices which means nothing but a slice of pizza 🍕. If we want to manage the state of user login flow we can define a slice as loginSlice and if we want to manage the state of todo tasks in the store, we can define a slice as tasksSlice.

Slices contains state managed variables and reducers (functions to change the state or do any other work).

Then comes the root Reducer which is a combined reducer of all the slices defined like userSlice tasksSlice etc.

📍 We use dispatchers to dispatch the payload or event to the store and selectors to fetch the latest state of the store


## 📌 Let's see in the code

Now, we want to pass login information of the user to the todo home component via redux store.


To use react redux make sure you have installed react redux

```BASH
npm install @reduxjs/toolkit
npm install react-redux
npm install redux
```
- Let's define the login Reducer
```JAVASCRIPT
import { createSlice } from "@reduxjs/toolkit";

const initialState = {
    user: null,
  };

  
const loginSlice = createSlice({
    name: "login",
    initialState,
    reducers: {
      setUser: (state, action) => {
        state.user = action.payload.name;
      },
      clearUser: (state) => {
        state.user = null;
      },
    },
  });
  
export const { setUser, clearUser } = loginSlice.actions;
export default loginSlice.reducer;

```

- To define the root reducer

```JAVASCRIPT
// rootReducer.js
import { combineReducers } from "redux";
import loginReducer from "./loginReducer";

const rootReducer = combineReducers({
  login: loginReducer,
  // Add other reducers here if needed
});

export default rootReducer;
```

- To use this reducer we need to provide a store to our whole app as:-

```JAVASCRIPT
import React from "react";
import ReactDOM from "react-dom/client";
import "./index.css";
import App from "./App";
import { BrowserRouter } from "react-router-dom";
import { createStore } from "redux";
import { Provider } from "react-redux";
import rootReducer from "./Components/rootReducer";


const root = ReactDOM.createRoot(document.getElementById("root"));
const store = createStore(rootReducer);
root.render(
  <React.StrictMode>
    <BrowserRouter>
      <Provider store={store}>
        <App />
      </Provider>
    </BrowserRouter>
  </React.StrictMode>
);

```

- Now while logging in, we need to send the payload to our store as 

```JAVASCRIPT
import React, { useState } from "react";
import "./Login.css";
import { useNavigate } from "react-router-dom";
import axios from "axios";
import { useDispatch } from "react-redux";
import { setUser } from "./loginReducer";

const Login = () => {
  const navigate = useNavigate();
  const [name, setName] = useState("");
  const [password, setPassword] = useState("");
  const dispatch = useDispatch();

  const handleLogin = async () => {
    try {
      const response = await axios.get("http://localhost:4000/users");
        console.log(response);
      const user = response.data.find((userData)=>userData.name === name && userData.password === password);
        if (user) {
        console.log("Login successful");
        dispatch(setUser(user));
        // Redirect to the homepage or any other desired page
        navigate("/home", {state: {username: name}});
      } else {
        console.error("Login failed");
        // Handle login failure, e.g., show an error message
      }
    } catch (error) {
      console.error("Error logging in:", error);
      // Handle login error, e.g., show an error message
    }
  };
  const handleSignUp = () => {
    navigate("/signup");
  };
return (----)
```

Focus on how we are dispatching the payload using useDispatch() hook

- Now on the todo homepage to fetch the user stored in the store by the login component

```JAVASCRIPT
import React, { useEffect, useRef, useState } from "react";
import "./Todo.css";
import axios from "axios";
import { useSelector} from "react-redux";

const Todo = () => {
  const username = useSelector((state) => state.login.user);
  
  const [tasks, setTasks] = useState([]);
  const taskInputRef = useRef(null);
----
```


🚀 That's it, you have successfully integrated your app with Redux.

That was it for today, Subscribe our YouTube channel to show your support to our efforts ❤️