【问题标题】:How to pause the delay of a component before state transition?如何在状态转换之前暂停组件的延迟?
【发布时间】:2016-07-02 06:49:35
【问题描述】:

在呈现页面之前,我有一组要调用的 AJAX 请求。我正在使用反应路由器 2.4.1。在我之前的一个项目中,使用了旧版本的 react-router,这就是我用来处理这个问题的方式

Router.run(RouteConfig, function(Handler, state){
    var promises = state.routes.filter(function(route) {
        //Every component that needs initial data for rendering will 
        //define a function fetchData in its statics which will return
        //a promise that will be resolved once all required AJAX calls             
        //are made.
        return route.handler.fetchData;
    }).map(function(route) {
        return route.handler.fetchData(state.params, state.query);
    });
    if(promises.length > 0) {
        Promise.all(promises).then(function(response) {
            data = response;
            //Rendering will happen only after every call is resolved
            render(Handler, data);
        }).catch(function(response, err) {
            data = response;
            data.isError = true;
            data.splice(err.index, 1, err.reason);
            render(Handler, data);
        });
    } else {
        render(Handler, data);
    }
});

function render(Handler, data) {
    React.render(<Handler data={data}/>, document.body);
}

在新版本中,我看到没有Router.run。如何在 2.4.1 中实现同样的效果?

【问题讨论】:

    标签: javascript reactjs redux react-router react-redux


    【解决方案1】:

    您可以尝试使用路由器提供的 onEnter 钩子。我将使用 React Router 展示我当前的设置。请记住,我声明了对路由而不是组件的依赖关系,但您可以更改该行为以满足您的需求。

    以这个路线列表为例:

    <Route path="/" onEnter={fetchDependencies} component={AppContainer}>
      <IndexRedirect to="/home" />
      <Route path="/home" component={StaticContainer} require={loadStaticPage} />
      <Route path="/contact" component={StaticContainer} require={loadStaticPage} />
    </Route>
    

    我将自己的处理程序添加到顶级路由器以获取每个依赖项,为此您只需在属性onEnter 上设置一个函数。我在需要一些依赖的路由上也有一个自定义属性,我将该属性命名为 require,它可以只是一个返回承诺的函数。在您的情况下,请使用该组件。

    此 onEnter 采用具有以下签名的函数:

    onEnter(nextState, replace, callback?)

    回调是可选的,如果提供,路由器将不会渲染组件,直到回调被调用且没有任何错误。那是你假装的行为。

    这就是我获取依赖项的方式,您可以调整此代码以满足您的需求

    function fetchDependencies(toRoute, redirect, done) {
      const { routes, params, location } = toRoute;
      const payload = Object.assign({}, location, { params });
      const promises = routes
        .map( ({ require }) => require )
        .filter( f => typeof f === 'function' )
        .map( f => f(payload) );
    
      return Promise.all(promises).then( () => done() , done);
    }
    

    在您的情况下,您可以使用组件而不是 require 属性。只需更改 map 函数以返回它。所以这一行

    .map( ({ require }) =&gt; require )

    会变成类似的东西

    .map( ({ component }) =&gt; component.fetchData )

    这只是一个想法,我粘贴的代码只是我使用的设置的简化版本。我当前的设置与 Redux 相关联,我试图删除该示例中关于 redux 的所有引用,这就是为什么它可能不完全有意义。我也使用同构渲染,所以我的处理程序有点复杂,我不需要客户端上的回调,因为一旦获取依赖项,redux 就会处理重新渲染。

    但是你得到了基本的想法。您需要使用 onEnter 钩子。完成后,您可以在那里获取所有依赖项并调用回调函数。它就像您的旧设置一样,但组织方式略有不同。

    【讨论】:

      猜你喜欢
      • 2013-01-14
      • 2023-03-14
      • 1970-01-01
      • 2017-12-24
      • 2013-02-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多