首页 > 解决方案 > useNavigate 未在登录 v6 react-router-dom 上重定向

问题描述

在提交表单时,useNavigate 钩子应该检测到 isAuthenticated 状态并重定向到“/app/dashboard”路由,但它仍然在“/login”路由上

App.js 这里的 isAuthenticated 被传递给路由并根据其全局布尔值呈现相关路由

import React from "react";
import jwtDecode from "jwt-decode";

// Routing
import { useRoutes } from "react-router-dom";
import routes from "./routes"

const token = localStorage.FBIdToken;

let isAuthenticated;

if (token) {
  const decodedToken = jwtDecode(token);
  console.log(decodedToken);
  //  Check whether the token is expired
  if (decodedToken.exp * 1000 < Date.now()) {
    window.location.href = "/login";
    isAuthenticated = false;
  } else {
    isAuthenticated = true;
  }
}

function App() {
  const routing = useRoutes(routes(isAuthenticated));

  return (
    <ThemeProvider theme={theme}>
      <GlobalStyles />
      {routing}
    </ThemeProvider>
  );
}

export default App;

routes.js 传递了 isAuthenticated 来确定将显示哪个视图

import React from "react";
import { Navigate } from "react-router-dom";
const routes = (isAuthenticated) => [
  {
    path: "/app",
    element:
      isAuthenticated === true ? <DashboardLayout /> : <Navigate to="/login" />,
    children: [{ path: "dashboard", element: <Dashboard /> }],
  },
  {
    path: "/",
    element: !isAuthenticated ? (
      <MainLayout />
    ) : (
      <Navigate to="/app/dashboard" />
    ),
    children: [
      { path: "login", element: <Login /> },
      { path: "signup", element: <Signup /> },
      { path: "/", element: <Navigate to="/app/dashboard" /> },
    ],
  },
];

export default routes;

login.js 发送了一个 axios 请求,成功的响应应该导致页面重定向到“/app/dashboard”路由

import React, { useState } from "react";
import { Link as RouterLink, useNavigate } from "react-router-dom";
const Login = () => {
  const classes = useStyles();
  const navigate = useNavigate();

  const [state, setState] = useState({
    email: "",
    password: "",
    loading: false,
    errors: {},
  });

  const handleChange = (e) => {
    // Set the value of state to corresponding input
    setState({
      ...state,
      [e.target.name]: e.target.value,
    });
  };

  const handleSubmit = (e) => {
    e.preventDefault();

    setState({
      ...state,
      loading: true,
    });

    const userData = {
      email: state.email,
      password: state.password,
    };

    axios
      .post("/login", userData)
      .then((response) => {
        console.log(response.data);

        localStorage.setItem("FBIdToken", `Bearer ${response.data.token}`);

        setState({
          ...state,
          loading: false,
        });

        navigate("/app/dashboard", { replace: true });
      })
      .catch((err) => {
        setState({
          ...state,
          errors: err.response.data,
          loading: false,
        });
      });
  };

  return (
    // Some form
  );
};

export default Login;

标签: reactjsredirectreact-router-dom

解决方案


我采用的方法很肮脏,但它对历史版本 5.0.0 的作用仍然不大

src/utils/history.js

import { createBrowserHistory } from "history"
export default createBrowserHistory();

src/pages/auth/login.js

import React, { useState } from "react";
import { Link as RouterLink} from "react-router-dom";
import history from "../../utils/histroy";

const Login = () => {
  const classes = useStyles();
  const navigate = useNavigate();

  const [state, setState] = useState({
    email: "",
    password: "",
    loading: false,
    errors: {},
  });

  const handleChange = (e) => {
    // Set the value of state to corresponding input
    setState({
      ...state,
      [e.target.name]: e.target.value,
    });
  };

  const handleSubmit = (e) => {
    e.preventDefault();

    setState({
      ...state,
      loading: true,
    });

    const userData = {
      email: state.email,
      password: state.password,
    };

    axios
      .post("/login", userData)
      .then((response) => {
        console.log(response.data);

        localStorage.setItem("FBIdToken", `Bearer ${response.data.token}`);

        setState({
          ...state,
          loading: false,
        });

        history.push("/app/dashboard");
        histrory.go();
      })
      .catch((err) => {
        setState({
          ...state,
          errors: err.response.data,
          loading: false,
        });
      });
  };

  return (
    // Some form
  );
};

export default Login;

推荐阅读