在 React 中单击导航栏标题上的注销按钮后,如何重定向到登录页面? [英] How to redirect to log in page after click logout button on navbar header in React?

查看:47
本文介绍了在 React 中单击导航栏标题上的注销按钮后,如何重定向到登录页面?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是 React 的新手.我在 App.js 中有这样的反应路由器配置:

<div className="应用程序"><标题/><开关><路由精确路径="/" component={Home}></路线><路由精确路径="/management" component={Management}></路线><路由精确路径="/sign-up" component={SignUpForm}></路线><路由精确路径="/sign-in" component={SignInForm}></路线><路由组件={错误}></路线></开关>

</BrowserRouter >

我希望标题显示在每个页面中,标题处有一个注销按钮,我想在单击它后重定向到/sign-in 页面.在我的标题组件中,它是这样的:

class Header extends Component {构造函数(道具){超级(道具);this.state = {重定向:假}}注销 = () =>{sessionStorage.setItem("userToken", '');sessionStorage.clear();this.setState({redirect: true });}使成为() {如果(this.state.redirect){返回 (<重定向到={'/sign-in'}/>)}返回 (<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}>注销</button></导航></Navbar.Collapse></导航栏>

);}}导出默认标题;

会出现错误警告:您试图重定向到您当前所在的同一路线:"/登录,并且导航栏将仅消失登录显示的正文.我知道是什么吗这样做的正确方法是什么?我也试过 this.props.history.push('/sign-in') 但没有 props.history,可能是因为 header 不在路由中?我应该与路由器一起使用吗?或者我应该实际上只是让每个页面导入标题而不是将其放在 app.js 中?或者实际上正确的方法是什么?非常感谢您的帮助!

解决方案

您可以使用 HOC 实现使用路由的登录/注销,该 HOC 在每次路由更改时检查会话项.如果会话有 userToken 那么它将重定向到给定的组件,否则将重定向到登录组件.

从react"导入 React从react-router-dom"导入{重定向}export const PrivateRoute = ({component: Component, ...rest}) =>(<Route {...rest} render={(props) =>(sessionStorage.getItem('userToken') ?<组件{...道具}/>:<重定向到=/登录"/>)}/>)

import 并作为授权路径使用.并将所有其他路径保留为您不需要授权的正常路径.

<div className="应用程序"><标题/><开关><PrivateRoute path="/" component={Home}/><PrivateRoute path="/management" component={Management}/><Route path="/sign-up" component={SignUpForm}/><Route path="/sign-in" component={SignInForm}/><路由组件={Error}/></开关>

</BrowserRouter >

因此,当您注销时,会话项将被删除并自动重定向到登录页面.

class Header extends Component {....注销 = () =>{sessionStorage.removeItem("userToken");sessionStorage.clear();}使成为() {返回 (<div>...<button type='button' onClick={this.logout}>注销</button>

)}}导出默认标题;

I'm new to React. I have react router config in App.js like this:

<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 >

I want header to show in every page, there's a button of logout at header, I want to redirect to /sign-in page after I click it. In my header component it's like this:

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;

There will be errors "Warning: You tried to redirect to the same route you're currently on: "/sign-in", and the nav bar will disappear only the body of sign-in shows. May I know what is the correct way to do this? I also tried this.props.history.push('/sign-in') but there's no props.history, probably because header is not in route? Should i use with Router? Or should I actually just make every page import header instead put it in app.js? or what is actually the right way to do this? Thank you so much for your help!

解决方案

You can implement login/logout with route using HOC that checks the session item with every route change. If the session has userToken then it will redirect to given component otherwise will redirect to login component.

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"/>
    )} />
)

import <PrivateRoute> and use it as the authorized path. And keep all the other path as normal routes in which you don't want authorization.

<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 >

So while you do log out, the session item will be removed and automatically redirect to sign-in page.

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 中单击导航栏标题上的注销按钮后,如何重定向到登录页面?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
其他开发最新文章
热门教程
热门工具
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆