【问题标题】:How to access redux store in private route?如何在私有路由中访问 redux 商店?
【发布时间】:2026-01-05 08:55:01
【问题描述】:

我正在尝试从我的 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 };

【问题讨论】:

    标签: reactjs redux redux-toolkit


    【解决方案1】:

    当 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" />
      );
    };
    

    只要确保你像任何其他常规Route 组件一样渲染AdminRoute

    例如:

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

    【讨论】:

    • 如果我对路由使用最后一种方法,我可以在管理路由中看到更新的状态,但之后该路由不再受保护。