反应-登录到尝试页面后进行路由和重定向

时间:2018-06-26 07:10:39

标签: reactjs redirect react-router

实施react-router 4的最佳实践是什么?目前,我创建了两个组件,PrivateRoutePublicRoutePublicRoute用于/login路径,它呈现Login组件,而PrivateRoute用于其余路径,并且如果用户已登录或重定向,它将呈现传递的Component。 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>

);

如果未登录,如何实现到尝试页面的重定向?

3 个答案:

答案 0 :(得分: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('/');
   }
}

答案 1 :(得分:0)

您应使用组件的生命周期方法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)

答案 2 :(得分:0)

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

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

请勿在{{1​​}}中使用它-它会被连续调用。