如何在私有路由中访问 redux 存储?

时间:2021-07-09 06:11:54

标签: reactjs redux redux-toolkit

我正在尝试从我的 redux 存储中通过私有路由访问身份验证状态。我可以获得默认状态,但无法从商店获取更新状态。我已将当前用户数据和令牌存储在商店中。除了我的私有路由组件,我可以从所有其他组件访问这些值。 我在下面提供了一些代码

<块引用>

AdminRoute.js

import React from "react";
import { useSelector } from "react-redux";
import { Route, Redirect } from "react-router-dom";

const AdminRoute = ({ component: Component, ...rest }) => {
  const authState = useSelector((state) => state.authState);
  console.log(authState.currentUser);
  return (
    <Route
      {...rest}
      render={(props) =>
        authState.currentUser?.id ? (
          <Component {...props} />
        ) : (
          <Redirect to="/auth" />
        )
      }
    />
  );
};

export default AdminRoute;
<块引用>

Store.js

import { configureStore } from "@reduxjs/toolkit";
import { uiReducer } from "../slices/uiSlice";
import { authReducer } from "../features/auth/authSlice";
import { userReducer } from "../features/user/userSlice";

export default configureStore({
  reducer: {
    uiState: uiReducer,
    authState: authReducer,
    userState: userReducer,
  },
});

authSlice.js

import { createSlice, createAsyncThunk } from "@reduxjs/toolkit";
import { apiUrl } from "../../api/apiConfig";
import Axios from "axios";
import { tokenConfig } from "../../utils/tokenConfig";

export const userLogin = createAsyncThunk(
  "auth/userLogin",
  async (userData, { rejectWithValue, dispatch }) => {
    const { email, password } = userData;
    try {
      const { data } = await Axios.post(`${apiUrl}/auth/login`, {
        email,
        password,
      });
      if (data) {
        localStorage.setItem("token", data.token);
        return data;
      }
    } catch (err) {
      if (!err.response) {
        throw err;
      }
      return rejectWithValue(err.response.data?.msg);
    }
  }
);

export const getCurrentUser = createAsyncThunk(
  "auth/getCurrentUser",
  async (_, { rejectWithValue, getState }) => {
    try {
      const { data } = await Axios.get(
        `${apiUrl}/user/cUser`,
        tokenConfig(getState)
      );
      if (data) {
        return data;
      }
    } catch (err) {
      if (!err.response) {
        throw err;
      }
      return rejectWithValue(err.response.data?.msg);
    }
  }
);

const authSlice = createSlice({
  name: "auth",
  initialState: {
    token: localStorage.getItem("token"),
    isLoggedIn: false,
    currentUser: null,
  },
  extraReducers: {
    [userLogin.pending]: (state, action) => {
      state.status = "loading";
    },
    [userLogin.fulfilled]: (state, action) => {
      state.status = "success";
      state.isLoggedIn = true;
      state.token = action.payload.token;
    },
    [userLogin.rejected]: (state, action) => {
      state.status = "failed";
      state.error = action.payload;
    },
    [getCurrentUser.pending]: (state, action) => {
      state.status = "loading";
    },
    [getCurrentUser.fulfilled]: (state, action) => {
      state.status = "success";
      state.currentUser = action.payload;
      state.isLoggedIn = true;
    },
    [getCurrentUser.rejected]: (state, action) => {
      state.status = "failed";
      state.error = action.payload;
    },
  },
});
 const { actions: authActions, reducer: authReducer } = authSlice;
 export { authActions, authReducer };

1 个答案:

答案 0 :(得分:0)

当 redux 状态更新时,您的受保护路由似乎应该重新渲染。也许您可以消除一些复杂性。

import React from "react";
import { useSelector } from "react-redux";
import { Route, Redirect } from "react-router-dom";

const AdminRoute = (props) => {
  const authState = useSelector((state) => state.authState);
  return authState.currentUser?.id ? (
    <Route {...props} />
  ) : (
    <Redirect to="/auth" />
  );
};

并确保您像任何其他常规 AdminRoute 组件一样渲染 Route

例如:

  • <AdminRoute path="/protected" component={PrivateComponent} />
    
  • <AdminRoute
      path="/protected"
      render={props => <PrivateComponent {...props} />}
    />
    
  • <AdminRoute path="/protected">
      <PrivateComponent />
    </AdminRoute>