React Redux in one shot while building a Project

server side digest - Jun 28 '23 - - Dev Community

๐Ÿš€ 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

๐Ÿ˜‚ No, I am just kidding. React Redux is very easy to learn.

*Note:- * You can also find the YouTube video 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

and the homepage of the app looks like this:-

Homepage

โšก๏ธ 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

๐Ÿ˜ฉ 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

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

npm install @reduxjs/toolkit
npm install react-redux
npm install redux
Enter fullscreen mode Exit fullscreen mode
  • Let's define the login Reducer
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;

Enter fullscreen mode Exit fullscreen mode
  • To define the root reducer
// rootReducer.js
import { combineReducers } from "redux";
import loginReducer from "./loginReducer";

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

export default rootReducer;
Enter fullscreen mode Exit fullscreen mode
  • To use this reducer we need to provide a store to our whole app as:-
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>
);

Enter fullscreen mode Exit fullscreen mode
  • Now while logging in, we need to send the payload to our store as
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 (----)
Enter fullscreen mode Exit fullscreen mode

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
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);
----
Enter fullscreen mode Exit fullscreen mode

๐Ÿš€ 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 โค๏ธ

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .