【问题标题】:Possible to delay component rendering with `onEnter`?可以使用“onEnter”延迟组件渲染吗?
【发布时间】:2016-09-16 22:26:29
【问题描述】:

我正在使用 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() 之前渲染/安装。理想情况下,渲染会等到回调被触发。

我是否误解了它的工作原理?有没有办法延迟渲染路由组件,直到某些条件成立?

【问题讨论】:

    标签: javascript reactjs redux react-router


    【解决方案1】:

    永远不要延迟路线渲染,您的用户应该得到更好的。

    绝对有一种不同的方法可以做到这一点,那就是让您呈现的实际页面包含用于查看是否有人有权查看它的逻辑,起始 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 应用程序管理的页面更改为下一个,因此您可以使用应用程序全局跟踪器。

    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();
      },
      ...
    });
    

    【讨论】:

    • 这些想法真的很棒,谢谢!然而,感觉这应该更多地以“重定向”的方式处理。你认为未经授权的用户浏览器不应该被重定向到/login之类的地方吗?
    • 我没有。 URL 旨在成为 Internet(网络或其他)上的稳定资源单元,神奇地更改某人认为他们正在关注的链接打破了预期惹恼了您的用户。相反,呈现他们想要的页面,但转到“您尚未登录。这是登录表单。在这里,无需单击其他任何地方,只需填写此内容,点击登录,甚至无需重新加载您的页面”将获得您正在寻找的内容”。是的,您应该有一个专用的/login 路由,您的用户可以显式调用它,但您不需要重定向到它。这是反应。
    • 详细说明“它是 React”:您的登录页面应该合理地使用模块化组件来处理登录 - 当用户尚未授权并完成时,也只需在其他页面上使用该组件即可。登录组件可以包含所有授权代码,您可以简单地使用 onAuthorized={authorized =&gt; this.setState({ authorized })} 属性引导它,以确保它自动为将其加载到其 UI 中的任何页面执行正确的操作。
    猜你喜欢
    • 2011-07-07
    • 2020-11-14
    • 2015-08-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-05-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多