reactjs - 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;
解决方案
我采用的方法很肮脏,但它对历史版本 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;
推荐阅读
- python - 如何使用 matplotlib 创建随机点大小
- c++ - 在这个项目中如何避免循环依赖?
- javascript - 创建一个用“假”填充的数组数组
- bash - 附加到函数的最后(或第 n 个)行(使用 awk/sed)
- javascript - 资源时间轴:事件函数仅在按下 prev 或 next 按钮时调用,但在滚动时间轴时不调用
- heroku - 使用在 Heroku 上运行的 Discord Bot 的用户屏幕出现问题
- chart.js - 动态改变chartjs刻度颜色
- python - 如何在获取的字典和列表的 json 中打印键和值?
- reactjs - TypeScript 中的自定义 React 钩子 - 没有调用签名
- java - 使用 Java 和 JPL 从 SWI-Prolog 检索错误消息