可以使用`onEnter`来延迟组件渲染吗?

时间:2016-09-16 22:26:30

标签: javascript reactjs redux react-router

我正在使用React Router onEnter属性来处理身份验证,如下所示,以及"auth-flow" example中所示。

   function requireAuth(nextState, replace, next) {
     Auth.validateToken()
       .then(() =>  {
         next();
       })
       .fail(() => {
         replace('/login');
         next();
       }); 
   }

   <Router history={history}>
      <Route path="/" component={App} >
        <IndexRoute
          component={Dashboard}
          onEnter={requireAuth}
        />
        <Route
          path="login"
          component={LogInForm}
        />
      </Route>
    </Router>

我正在使用onEnter的异步回调功能,因为我的令牌验证需要服务器调用。

我遇到的问题是此示例中的Dashboard组件在调用next()之前呈现/安装。理想情况下,渲染会等到回调被触发。

我是否误解了这是如何工作的?有没有办法延迟路由组件的渲染,直到某些条件成立为止?

1 个答案:

答案 0 :(得分:3)

不要拖延路线渲染,您的用户应该得到更好的效果。

完全有另外一种方法可以做到这一点,并且通过让您呈现的实际页面包含用于查看某人是否有权查看它的逻辑,并以state开头它的内容类似于authorized: false,并且您的回调会使用this.setState({ authorized: resultFromCallback })切换。

状态更改将导致React在您的网页上再次呼叫render()如果值不同,然后在您的网页render()功能中只需检查this.state.authorized,看看您是否应该向用户显示一个UI,其中包含他们应该看作匿名用户的所有位,或者他们应该看作授权用户的所有位。

...
  componentDidount() {
    whateverlib.checkForAuthorization(this.handleAuthorization);
  },
  handleAuthorization(authorized) {
    this.setState({ authorized });
  },
  render() {
    if(this.state.authorized) {
      return this.renderAuthorizedUI();
    }
    return this.renderAnonymousUI();
  },
...

另外请记住,您的应用仍然只是在网页上运行的JavaScript ,那么为什么您甚至会检查您加载的每个页面?您需要做的就是检查任何页面,存储结果并完成。只要用户保持其选项卡处于打开状态,其授权状态就不会自动从一个react-router应用程序管理页面更改为下一个,因此您可以使用app-global tracker。

var authorizer = require('./lib/whatever-thing-you-wrote-for-this');

var YourPage = React.createClass({
  ...
  componentDidMount() {
    if (!authorizer.isAuthorized()) {
      authorizer.tryAuthorize(this.handleAuthorization);
    }
  },
  handleAuthorization() {
    this.forceUpdate();
  },
  render() {
    if(authorizer.isAuthorized()) {
      return this.renderAuthorizedUI();
    }
    return this.renderAnonymousUI();
  },
  ...
});