在提交表单时,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;
答案 0 :(得分:0)
我采用的方法很脏,但它对历史版本 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;
答案 1 :(得分:0)
useNavigate 没有问题。问题是传递给我的路由的布尔参数。这是我解决它的方法
创建了一个名为 src/redux/reducers/authReducer 的文件
import * as actionType from "../types";
let decodedUser = localStorage.getItem("SomeToken");
// Initialize state to match auth state
const initialState = decodedUser
? { isAuthenticated: true }
: { isAuthenticated: false };
export default function (state = initialState, action) {
switch (action.type) {
case actionType.SET_AUTHENTICATED:
return {
...state,
isAuthenticated: true,
};
// Unauthenticated is in the userReducer
default:
return state;
}
}
将reducer持久化到store中的组合reducer
const reducers = combineReducers({
auth: authReducer,
});
然后在 App.js 中执行以下操作
function App() {
const { isAuthenticated } = useSelector((state) => state.auth);
const routing = useRoutes(routes(isAuthenticated));
return (
<div>Some filler code</div>
);
}
然后在正在执行的操作中调用操作类型。例如
userAction.js
import * as actionType from "../types";
export const login = (data) => (dispatch) =>{
dispatch({type: actionType.SET_AUTHENTICATED });
}
参考:https://bezkoder.com/react-hooks-redux-login-registration-example/