javascript - 条件满足后私有(private)路由不重定向

我的私有(private)路由在满足条件后不会重定向。在我的例子中,当管理员点击登录时,它必须检查 token 是否在本地存储中,如果没有 token ,那么它必须重定向到登录页面,如果 token 在那里,它必须重定向到主页。 但是当我尝试访问主页时没有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",
};

最佳答案

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

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

您也可以通过useEffect 钩子(Hook)实现相同的逻辑,如下例:

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</>)
}

https://stackoverflow.com/questions/70419346/

相关文章:

rust - 在这种情况下如何决定生命周期注解?

c++ - sfinae 与非类型模板参数的概念

pytorch - Pytorch 中软标签的交叉熵

python - pandas 的过滤功能 - 在列中查看 NaN 值

reactjs - 如何在 React 中使用 map 输出嵌套对象的内容?

python - 从云函数内部构建容器镜像

fortran - gfortran 与 MKL 的链接导致 'Intel MKL ERROR: P

angular - Auth0 Angular error during unit test : U

python - 使用 Pandas 过滤列中具有唯一值的行

ios - FaSTLane Match 环境变量未被 build_app 获取