React - 登录到尝试页面后的路由和重定向

Posted

技术标签:

【中文标题】React - 登录到尝试页面后的路由和重定向【英文标题】:React - Routing & Redirect after login to attempted page 【发布时间】:2018-12-04 19:42:42 【问题描述】:

实施 react-router 4 的最佳实践是什么?目前我创建了两个组件,PrivateRoutePublicRoutePublicRoute 用于/login 路径,它呈现Login 组件,PrivateRoute 用于其余路径,如果用户登录或重定向,它呈现传递的组件。 PrivateRoute 代码是:

const PrivateRoute = (component: Component, ...rest) => (
<Route ...rest render=(props) => (
    helpers.getCurrentUser()
        ? (
            <div className="wrapper">
                <Sidebar/>
                <div id="content">
                    <Navbar/>
                    <Component ...props/>
                    <Footer/>
                </div>
            </div>
        ) :
        <Redirect
            to=
                pathname: "/login",
                state: from: props.location
            
        />
)/>

);

而同一文件中的Router 组件是:

export default () => (
<Router history=history>
    <Switch>
        <Route exact path='/login' component=PublicRoute/>
        <PrivateRoute exact path="/" component=Dashboard/>
        <PrivateRoute exact path="/users" component=UsersComponent/>
        <PrivateRoute exact path="/logs" component=LogsComponent/>
        <PrivateRoute exact path="/project" component=ProjectComponent/>
        <PrivateRoute exact path="/user" component=UserComponent/>
    </Switch>
</Router>

);

如果没有记录,如何实现重定向到尝试页面?

【问题讨论】:

您的意思是用户登录成功后如何将用户重定向到尝试的页面? 【参考方案1】:

由于您已经将来自的位置作为位置状态传递给 PrivateRoute 中的重定向,因此您可以在从登录组件重定向回来时使用相同的位置

在登录组件中您将拥有

onSuccessLogin = () => 
   const location = this.props;
   if(location.state && location.state.from) 
      this.props.history.push(location.state.from);
    else 
      this.props.history.push('/');
   

【讨论】:

【参考方案2】:

您应该使用组件的生命周期方法componentDidUpdate 来处理路由的更新,如react-router-4 migration guide 中所述。

例如:

class AppContainer extends React.Component 
  render() 
    return (
      <BrowserRouter>
        <div>
          <Route path='*' component=RootRoute/>
        </div>
      </BrowserRouter>
    )
  


class RootRoute extends React.Component 
  static propTypes = 
    history: PropTypes.object, // this prop comes from withRouter feature
    location: PropTypes.object, // this prop comes from withRouter feature
    user: PropTypes.object // this prop should come from your App
  

  componentDidUpdate() 
    this.checkSession(
      location: this.props.location.pathname,
      user: this.props.user
    )
  

  checkSession(location, user) 
    if (!user.isLogged() && !user.isLocationPublic(location)) 
      this.props.history.push('/login')
    
  

  render() 
    return (
      <div>
        <Switch>
          <Route path='/login' component=LoginRoute/>
          <Route path='/backoffice' component=BackOfficeRoute/>
        </Switch>
      </div>
    )
  


export default withRouter(RootRoute)

【讨论】:

【参考方案3】:

结合上面的两个答案,这对我有用:

  componentWillUnmount() 
    const location = this.props;
    if(location.state && location.state.from) 
      this.props.history.push(location.state.from.pathname);
     else 
      this.props.history.push('/');
    
  

不要在componentDidUpdate 中这样做——它会被连续调用。

【讨论】:

以上是关于React - 登录到尝试页面后的路由和重定向的主要内容,如果未能解决你的问题,请参考以下文章

React 路由器路径验证和重定向

React 路由器会短暂显示登录屏幕,然后如果用户已登录,则会重定向到仪表板

Vue路由重定向、别名与导航守卫

转发以及重定向解析

servlet如何重定向

在 Codeigniter 中检查登录和重定向不起作用?