【问题标题】: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,那么它就会触发。

标签: javascript reactjs react-router react-router-dom


【解决方案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 谢谢。
猜你喜欢
  • 2023-02-22
  • 1970-01-01
  • 2020-10-22
  • 2017-02-20
  • 2020-11-12
  • 2014-12-19
  • 2017-09-17
  • 1970-01-01
  • 2019-11-13
相关资源
最近更新 更多