在 React 中单击导航栏 header 上的注销按钮后如何重定向到登录页面?
How to redirect to log in page after click logout button on navbar header in React?
我是 React 新手。我在 App.js 中有这样的 React 路由器配置:
<BrowserRouter>
<div className="App">
<Header />
<Switch>
<Route exact path="/" component={Home}>
</Route>
<Route exact path="/management" component={Management}>
</Route>
<Route exact path="/sign-up" component={SignUpForm}>
</Route>
<Route exact path="/sign-in" component={SignInForm}>
</Route>
<Route component={Error}>
</Route>
</Switch>
</div>
</BrowserRouter >
我想让header显示在每个页面,在header有一个注销按钮,我想在点击它后重定向到/sign-in页面。在我的 header 组件中是这样的:
class Header extends Component {
constructor(props) {
super(props);
this.state = {
redirect: false
}
}
logout = () => {
sessionStorage.setItem("userToken", '');
sessionStorage.clear();
this.setState({ redirect: true });
}
render() {
if (this.state.redirect) {
return (
<Redirect to={'/sign-in'} />
)
}
return (
<div>
<Navbar collapseOnSelect expand="md" bg="dark" variant="dark" fixed="top" >
......
<NavLink to="/management" className="header-link"><FontAwesomeIcon icon="cog" size="lg" /></NavLink>
<button type='button' onClick={this.logout}>Log Out</button>
</Nav>
</Navbar.Collapse>
</Navbar>
</div>
);
}
}
export default Header;
会出现错误"Warning: You tried to redirect to the same route you're currently on: "/sign-in",导航栏会消失,只有sign-in的body显示。请问什么是正确的怎么做?我也试过 this.props.history.push('/sign-in') 但没有 props.history,可能是因为 header 不在路由中?我应该与路由器一起使用吗?或者我应该让每个页面都导入 header 而不是把它放在 app.js 中?或者实际上正确的方法是什么?非常感谢您的帮助!
您在这里提到了两种方法。您可以使用将传递给您的组件的高阶组件 'withRouter' that gives components access to the history object. By using the history 对象作为道具,您可以推送到您想要的路线。
就我个人而言,我喜欢设置注销 links 来呈现一个包含注销逻辑的组件,并在完成后呈现重定向到登录。这样,用户可以根据需要直接进入注销 link,并且您可以根据需要从应用中的任何位置 link 进入,而无需重复逻辑。
在您的浏览器路由器中,您可以为“/logout”添加一个路径来呈现这样的组件(根据您的逻辑):
import React, { Component } from 'react';
import { Redirect } from 'react-router';
export default class LogOut extends Component {
state = {
redirect: false,
};
componentDidMount() {
sessionStorage.setItem("userToken", '');
sessionStorage.clear();
this.setState({ redirect: true });
}
render() {
return this.state.redirect ?
<Redirect to={'/sign-in'} /> :
null;
}
}
通常我会发出 ajax 请求来清除会话,然后在完成后设置状态,但你的都是服务器端的。
绑定到路由的组件可以访问历史对象作为道具,因此您可以根据需要更改它,例如注销。由于您的 Header 组件无法访问 history 对象,您将不得不使用较低级别的路由器来授予它访问 history 对象的权限:
import { Router } from "react-router"
import { createBrowserHistory } from "history"
const history = createBrowserHistory()
<Router history={history}>
<div className="App">
<Header history={history} />
<Switch>
<Route exact path="/" component={Home}>
</Route>
<Route exact path="/management" component={Management}>
</Route>
<Route exact path="/sign-up" component={SignUpForm}>
</Route>
<Route exact path="/sign-in" component={SignInForm}>
</Route>
<Route component={Error}>
</Route>
</Switch>
</div>
</Router>
现在您可以在 Header 组件中调用 history.push('/login')
参见参考文献:https://reacttraining.com/react-router/web/api/Router/history-object
您可以通过使用 HOC 的路由实现 login/logout,HOC 会在每次路由更改时检查会话项。如果会话有 userToken
那么它将重定向到给定的组件,否则将重定向到登录组件。
import React from "react"
import {Redirect} from "react-router-dom"
export const PrivateRoute = ({component: Component, ...rest}) => (
<Route {...rest} render={(props) => (
sessionStorage.getItem('userToken') ? <Component {...props} /> : <Redirect to="/sign-in"/>
)} />
)
导入<PrivateRoute>
并将其用作授权路径。并将所有其他路径保留为您不需要授权的正常路径。
<BrowserRouter>
<div className="App">
<Header />
<Switch>
<PrivateRoute path="/" component={Home} />
<PrivateRoute path="/management" component={Management} />
<Route path="/sign-up" component={SignUpForm} />
<Route path="/sign-in" component={SignInForm} />
<Route component={Error} />
</Switch>
</div>
</BrowserRouter >
因此当您注销时,会话项目将被删除并自动重定向到登录页面。
class Header extends Component {
....
logout = () => {
sessionStorage.removeItem("userToken");
sessionStorage.clear();
}
render() {
return (
<div>
...
<button type='button' onClick={this.logout}>Log Out</button>
</div>
)
}
}
export default Header;
我是 React 新手。我在 App.js 中有这样的 React 路由器配置:
<BrowserRouter>
<div className="App">
<Header />
<Switch>
<Route exact path="/" component={Home}>
</Route>
<Route exact path="/management" component={Management}>
</Route>
<Route exact path="/sign-up" component={SignUpForm}>
</Route>
<Route exact path="/sign-in" component={SignInForm}>
</Route>
<Route component={Error}>
</Route>
</Switch>
</div>
</BrowserRouter >
我想让header显示在每个页面,在header有一个注销按钮,我想在点击它后重定向到/sign-in页面。在我的 header 组件中是这样的:
class Header extends Component {
constructor(props) {
super(props);
this.state = {
redirect: false
}
}
logout = () => {
sessionStorage.setItem("userToken", '');
sessionStorage.clear();
this.setState({ redirect: true });
}
render() {
if (this.state.redirect) {
return (
<Redirect to={'/sign-in'} />
)
}
return (
<div>
<Navbar collapseOnSelect expand="md" bg="dark" variant="dark" fixed="top" >
......
<NavLink to="/management" className="header-link"><FontAwesomeIcon icon="cog" size="lg" /></NavLink>
<button type='button' onClick={this.logout}>Log Out</button>
</Nav>
</Navbar.Collapse>
</Navbar>
</div>
);
}
}
export default Header;
会出现错误"Warning: You tried to redirect to the same route you're currently on: "/sign-in",导航栏会消失,只有sign-in的body显示。请问什么是正确的怎么做?我也试过 this.props.history.push('/sign-in') 但没有 props.history,可能是因为 header 不在路由中?我应该与路由器一起使用吗?或者我应该让每个页面都导入 header 而不是把它放在 app.js 中?或者实际上正确的方法是什么?非常感谢您的帮助!
您在这里提到了两种方法。您可以使用将传递给您的组件的高阶组件 'withRouter' that gives components access to the history object. By using the history 对象作为道具,您可以推送到您想要的路线。
就我个人而言,我喜欢设置注销 links 来呈现一个包含注销逻辑的组件,并在完成后呈现重定向到登录。这样,用户可以根据需要直接进入注销 link,并且您可以根据需要从应用中的任何位置 link 进入,而无需重复逻辑。
在您的浏览器路由器中,您可以为“/logout”添加一个路径来呈现这样的组件(根据您的逻辑):
import React, { Component } from 'react';
import { Redirect } from 'react-router';
export default class LogOut extends Component {
state = {
redirect: false,
};
componentDidMount() {
sessionStorage.setItem("userToken", '');
sessionStorage.clear();
this.setState({ redirect: true });
}
render() {
return this.state.redirect ?
<Redirect to={'/sign-in'} /> :
null;
}
}
通常我会发出 ajax 请求来清除会话,然后在完成后设置状态,但你的都是服务器端的。
绑定到路由的组件可以访问历史对象作为道具,因此您可以根据需要更改它,例如注销。由于您的 Header 组件无法访问 history 对象,您将不得不使用较低级别的路由器来授予它访问 history 对象的权限:
import { Router } from "react-router"
import { createBrowserHistory } from "history"
const history = createBrowserHistory()
<Router history={history}>
<div className="App">
<Header history={history} />
<Switch>
<Route exact path="/" component={Home}>
</Route>
<Route exact path="/management" component={Management}>
</Route>
<Route exact path="/sign-up" component={SignUpForm}>
</Route>
<Route exact path="/sign-in" component={SignInForm}>
</Route>
<Route component={Error}>
</Route>
</Switch>
</div>
</Router>
现在您可以在 Header 组件中调用 history.push('/login')
参见参考文献:https://reacttraining.com/react-router/web/api/Router/history-object
您可以通过使用 HOC 的路由实现 login/logout,HOC 会在每次路由更改时检查会话项。如果会话有 userToken
那么它将重定向到给定的组件,否则将重定向到登录组件。
import React from "react"
import {Redirect} from "react-router-dom"
export const PrivateRoute = ({component: Component, ...rest}) => (
<Route {...rest} render={(props) => (
sessionStorage.getItem('userToken') ? <Component {...props} /> : <Redirect to="/sign-in"/>
)} />
)
导入<PrivateRoute>
并将其用作授权路径。并将所有其他路径保留为您不需要授权的正常路径。
<BrowserRouter>
<div className="App">
<Header />
<Switch>
<PrivateRoute path="/" component={Home} />
<PrivateRoute path="/management" component={Management} />
<Route path="/sign-up" component={SignUpForm} />
<Route path="/sign-in" component={SignInForm} />
<Route component={Error} />
</Switch>
</div>
</BrowserRouter >
因此当您注销时,会话项目将被删除并自动重定向到登录页面。
class Header extends Component {
....
logout = () => {
sessionStorage.removeItem("userToken");
sessionStorage.clear();
}
render() {
return (
<div>
...
<button type='button' onClick={this.logout}>Log Out</button>
</div>
)
}
}
export default Header;