[英]history.push to /login (on logout) is not working in react-router-dom
When the users logs in using his/her credentials, the name of the user is displayed on the Header
component.当用户使用他/她的凭据登录时,用户的名称会显示在
Header
组件上。 The user can log out using the logout
link.用户可以使用
logout
链接注销。
When the user clicks on the logout
link, I remove the loggedInUser
object saved in local storage.当用户单击
logout
链接时,我删除了保存在本地存储中的loggedInUser
object。 Then, I direct the user to the /login
route, where I show the login form to the user.然后,我将用户定向到
/login
路由,在那里我向用户显示登录表单。
When I use history.push("/login")
, and click on the logout
link, nothing happens.当我使用
history.push("/login")
并单击logout
链接时,没有任何反应。 The loggedInUser
object does not get removed from the local storage, and I am not directed to the login
route. loggedInUser
object 没有从本地存储中删除,我也没有被定向到login
路径。 However, if I use window.location = "/login"
, everything works as expected.但是,如果我使用
window.location = "/login"
,一切都会按预期工作。
Why is hitory.push("/login")
not working as expected?为什么
hitory.push("/login")
没有按预期工作?
Header.js: Header.js:
import React from "react";
import { Link, withRouter } from "react-router-dom";
import { useDispatch, useSelector } from "react-redux";
import { logout } from "./stateSlices/loginSlice";
const Header = ({ history }) => {
const { loggedInUser } = useSelector((state) => state.login);
const dispatch = useDispatch();
const logoutSubmitHandler = () => {
dispatch(logout());
localStorage.removeItem("loggedInUser");
window.location = "/login"; // THIS works
// history.push("/login"); // THIS does not work
};
return (
<header>
<nav>
<ul className="navbar-list">
{loggedInUser ? (
<div className="dropdown">
<button
className="btn btn-lg btn-primary dropdown-toggle"
type="button"
id="dropdownMenu2"
data-toggle="dropdown"
aria-haspopup="true"
aria-expanded="false"
>
{loggedInUser.firstName}
</button>
<div
className="dropdown-menu dropdown-menu-right"
aria-labelledby="dropdownMenu2"
>
<button
className="dropdown-item"
type="button"
onClick={logoutSubmitHandler}
>
Logout
</button>
</div>
</div>
) : (
<Link to="/login" className="navbar-list-item">
Register/Login
</Link>
)}
</ul>
</nav>
</header>
);
};
export default withRouter(Header);
App.js:应用程序.js:
import React from "react";
import Header from "./components/Header";
import { Route, Switch } from "react-router-dom";
import LoginForm from "./components/LoginForm";
import RegisterForm from "./components/RegisterForm";
import Welcome from "./components/Welcome";
import PasswordResetFormEmail from "./components/PasswordResetFormEmail";
import PasswordResetFormPassword from "./components/PasswordResetFormPassword";
const App = () => {
return (
<>
<Header />
<Switch>
<Route
path="/password/reset/:token"
component={PasswordResetFormPassword}
/>
<Route
path="/account/password/forgot"
component={PasswordResetFormEmail}
/>
<Route path="/register" component={RegisterForm} />
<Route path="/login" component={LoginForm} />
<Route path="/welcome" component={Welcome} />
</Switch>
</>
);
};
export default App;
index.js: index.js:
import React from "react";
import ReactDOM from "react-dom";
import "bootstrap/dist/css/bootstrap.min.css";
import "./index.css";
import App from "./App";
import reportWebVitals from "./reportWebVitals";
import { BrowserRouter as Router } from "react-router-dom";
import { Provider } from "react-redux";
import store from "./store";
ReactDOM.render(
<Provider store={store}>
<Router>
<App />
</Router>
</Provider>,
document.getElementById("root")
);
You have a typo in your redux slice:您的 redux 切片中有错字:
reducers: {
logout(state, action) {
// state.user = null; // <-- Typo error
state.loggedInUser = null; // This is the correct one
},
},
But, after fixing the typo, I would recommend that you refactor your code and create a "PrivateRoute" component as demoed in the docs :但是,在修复错字之后,我建议您重构代码并创建一个“PrivateRoute”组件,如文档中演示的那样:
const PrivateRoute = ({ children, ...rest }) => {
const { loggedInUser } = useSelector((state) => state.login);
return (
<Route
{...rest}
render={({ location }) =>
loggedInUser ? (
children
) : (
<Redirect to={{ pathname: "/login", state: { from: location } }} />
)
}
/>
);
};
and use it in App
component for all the private routes:并在
App
组件中为所有私有路由使用它:
<PrivateRoute path="/welcome">
<Welcome />
</PrivateRoute>
Now, this way, PrivateRoute
will take care of "redirection" to the login page, all you need to do is "clear" the loggedInUser
in your redux state.现在,通过这种方式,
PrivateRoute
将负责“重定向”到登录页面,您需要做的就是“清除” redux state 中的loggedInUser
。
Note that it is better to use "children" form when defining Routes.请注意,在定义 Routes 时最好使用“children”形式。 See What's the better way to configure routes in App.js in React with react-router-dom?
请参阅在 React 中使用 react-router-dom 在 App.js 中配置路由的更好方法是什么?
Try using:尝试使用:
import { useHistory } from "react-router-dom";
const history = useHistory();
const logoutSubmitHandler = () => {
history.push("/login");
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.