条件满足后,私有路由不重定向

Posted

技术标签:

【中文标题】条件满足后,私有路由不重定向【英文标题】:Private route is not redirecting after condition satisfy 【发布时间】:2022-01-21 22:11:12 【问题描述】:

我的私有路由在满足条件后没有重定向。在我的情况下,当管理员单击登录时,它必须检查令牌是否在本地存储中,如果没有令牌,那么它必须重定向到登录页面,如果有令牌,它必须重定向到主页。 但是当我尝试访问主页时没有toke,它会重定向到登录页面,但登录后它不会重定向到主页。 这是我的代码。

App.js

import "./App.css";
import  BrowserRouter as Router, Routes, Route  from "react-router-dom";
import Home from "./pages/Home";
import Login from "./pages/Login";
import Register from "./pages/Register";
import  PrivateRoute  from "./HOC/PrivateRoute";

function App() 
  return (
    <div className="App">
      <Router>
        <Routes>
          <Route
            path="/"
            element=
              <PrivateRoute>
                <Home />
              </PrivateRoute>
            
          />
          <Route exact path="/login" element=<Login /> />
          <Route exact path="/register" element=<Register /> />
        </Routes>
      </Router>
    </div>
  );


export default App;

PrivateRoute.js

import  Navigate  from "react-router-dom";

export function PrivateRoute( children ) 
  if (localStorage.getItem("token")) 
    return children;
   else 
    return <Navigate to="/login" replace />;
  

登录.js

import React,  useState  from "react";
import Layout from "../components/Layout/Layout";
import  Container, Form, Button, Row, Col  from "react-bootstrap";
import Input from "../components/UI/Input";
import  login  from "../redux/actions";
import  useDispatch, useSelector  from "react-redux";
import  Navigate  from "react-router-dom";

function Login(props) 
  const [email, setEmail] = useState("");
  const [userPassword, setUserPassword] = useState("");
  const [error, setError] = useState("");
  const auth = useSelector((state) => state.auth);
  const dispatch = useDispatch();
  const userLogin = (e) => 
    e.preventDefault();
    const user = 
      email,
      userPassword,
    ;
    dispatch(login(user));
  ;

  return (
    <Layout>
      <Container>
        <Row style= marginTop: "100px" >
          <Col md= span: 6, offset: 3 >
            <Form onSubmit=userLogin>
              <Input
                label="Email"
                type="text"
                placeholder="email"
                valu=email
                onChange=(e) => setEmail(e.target.value)
              />
              <Input
                label="Password"
                type="password"
                placeholder="Password"
                valu=userPassword
                onChange=(e) => setUserPassword(e.target.value)
              />
              <Button variant="primary" type="submit">
                Submit
              </Button>
            </Form>
          </Col>
        </Row>
      </Container>
    </Layout>
  );


export default Login;

auth.actions.js

import axios from "../../helpers/axios";
import  authConstants  from "./constants";

export const login = (user) => 
  console.log(user);
  return async (dispatch) => 
    dispatch( type: authConstants.LOGIN_REQUEST );
    const res = await axios.post("/auth/admin/login",  ...user );
    console.log(res);
    if (res.status === 200) 
      const  accessToken, ...user  = res.data;
      localStorage.setItem("token", accessToken);

      dispatch(
        type: authConstants.LOGIN_SUCCESS,
        payload:  user, accessToken ,
      );
     else 
      if (res.status === 400) 
        dispatch(
          type: authConstants.LOGIN_FAILURE,
          payload: 
            error: res.data.error,
          ,
        );
      
    
  ;
;

auth.reducers.js

import  authConstants  from "../actions/constants";

const initialState = 
  token: null,
  user: 
    firstName: "",
    lastName: "",
    email: "",
    picture: "",
  ,
  authenticate: false,
  authenticating: false,
;

    export default (state = initialState, action) => 
      console.log(action);
      switch (action.type) 
        case authConstants.LOGIN_REQUEST:
          state = 
            ...state,
            authenticating: true,
          ;
          break;
    
        case authConstants.LOGIN_SUCCESS:
          state = 
            ...state,
            user: action.payload.user,
            token: action.payload.accessToken,
            authenticate: true,
            authenticating: false,
          ;
      
      return state;
    ;

常量.js

export const authConstants = 
  LOGIN_REQUEST: "LOGIN_REQUEST",
  LOGIN_FAILURE: "LOGIN_FAILURE",
  LOGIN_SUCCESS: "LOGIN_SUCCESS",
;

【问题讨论】:

PrivateRoute.js 中你必须使用useEffect()。如果它得到token,那么它就会触发。 【参考方案1】:

实际上在用户登录后的那一刻,您不会从登录页面导航用户,您只是在更新 localStorage 而没有任何重定向。您可以像这样从登录页面导航:

function Login(props) 
  ...
  const auth = useSelector((state) => state.auth);
  ...
  if(auth.token)
   return <Navigate to="/" replace />
  
  return (<>login form</>)

你也可以通过useEffect钩子实现同样的逻辑,如下例:

import  useNavigate  from 'react-router-dom';
...
function Login(props) 
  const token = useSelector((state) => state.auth);
  const navigate = useNavigate();
  ...
  useEffect(()=> 
   if(token)
     navigate('/');
   
  , [token])
  ...
  return (<>login form</>)

【讨论】:

好答案.... @Mr.Perfectist 谢谢。

以上是关于条件满足后,私有路由不重定向的主要内容,如果未能解决你的问题,请参考以下文章

从一个控制器动作发布到另一个控制器动作(不重定向)

JSF过滤器在初始重定向后不重定向[关闭]

Django用户身份验证:登录后不重定向

使用 Django 和 AllAuth 登录后不重定向到我自己的视图

反应路由器私有路由/重定向不起作用

python - Django内置登录视图不重定向到下一个