Home > Back-end >  Passing the actual state to redux-toolkit
Passing the actual state to redux-toolkit

Time:01-21

Faced such a problem. There is an application on React redux-toolkit. The backend contains the authorization and verification logic for the jwt token. On the front end, I make a request to validate a user. If the correct answer came, I will dispatch this user to the state. Next, I want to forward this state to the child component to check if the user is authorized and display the desired page, or redirect to the login page. The essence of the problem is that an initial state is thrown into the child component, in which there is no user. Help solve the problem!

App.jsx

import { Routes, Route } from "react-router-dom";
import { useDispatch, useSelector } from "react-redux";
import { setUser } from "store/slices/userSlice";
import SignIn from "./components/SignIn/SignIn";
import SignUp from "./components/SignUp/SignUp";
import Main from "./components/Main/Main";
import { useEffect } from "react";
import { checkAuth } from "api";

function App() {
  const dispatch = useDispatch();
  const state = useSelector((state) => state);

  useEffect(() => {
    if (localStorage.getItem("email")) {
      checkAuth().then((data) => {
        dispatch(
          setUser({
            email: data.email,
            id: data.id,
            firstName: data.firstName,
            lastName: data.lastName,
            phone: data.phone,
            nickname: data.nickname,
            description: data.description,
            position: data.position,
            isAuth: true,
          })
        );
      });
    }
  }, []);

  return (
    <div className="App">
      <Routes>
        <Route path="/" element={<Main isAuth={state.user.isAuth} />} />
        <Route path="/signin" element={<SignIn />} />
        <Route path="/signup" element={<SignUp />} />
      </Routes>
    </div>
  );
}

export default App;

Дочерний компомнент

import { Navigate } from "react-router-dom";
import { useDispatch } from "react-redux";
import { removeUser } from "store/slices/userSlice";
import Header from "components/Header/Header";
import { logout } from "api/index";

const Main = ({ isAuth }) => { //тут приходит false
  const dispatch = useDispatch();

  const handleLogout = () => {
    logout();
    dispatch(removeUser());
  };

  return isAuth ? (
    <div>
      <Header handleLogout={handleLogout} />
      <h1>Welcome</h1>

      <button>Log out from</button>
    </div>
  ) : (
    <Navigate to="/signin" />
  );
};

export default Main;

Redux Slice

import { createSlice } from "@reduxjs/toolkit";

const initialState = {
  email: null,
  id: null,
  firstName: null,
  lastName: null,
  phone: null,
  nickname: null,
  description: null,
  position: null,
  isAuth: false,
};

const userSlice = createSlice({
  name: "user",
  initialState,
  reducers: {
    setUser(state, action) {
      state.email = action.payload.email;
      state.id = action.payload.id;
      state.firstName = action.payload.firstName;
      state.lastName = action.payload.lastName;
      state.phone = action.payload.phone;
      state.nickname = action.payload.nickname;
      state.description = action.payload.description;
      state.position = action.payload.position;
      state.isAuth = action.payload.isAuth;
    },
    removeUser(state) {
      state.email = null;
      state.token = null;
      state.id = null;
      state.firstName = null;
      state.lastName = null;
      state.phone = null;
      state.nickname = null;
      state.description = null;
      state.position = null;
      state.isAuth = false;
    },
  },
});

export const { setUser, removeUser } = userSlice.actions;

export default userSlice.reducer;

Tried to use useState, empty state is also forwarded

CodePudding user response:

Redux is the technology used for avoiding props drilling, and you are doing it further using Redux. So you should directly access user value directly from the Redux store using the useSelector hook in <Main/>.

  • Related