2016-07-02 13 views
1

ページをレンダリングする前に呼び出される一連のAJAXリクエストがあります。私は反応ルータ2.4.1を使用しています。反応-ルータの古いバージョンを使用し、私の以前のプロジェクトの一つでは、これは私がこの問題に対処するために使用方法を新しいバージョンには、その後状態遷移前のコンポーネントの遅延を一時停止する方法は?

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でどのように達成できますか?

答えて

2

ルータが提供するonEnterフックを使用できます。私はReact Routerで現在の設定を表示します。私はルート上ではなくコンポーネント上に依存関係を宣言していますが、その振る舞いを必要に応じて足元に変更することができます。

は、一例として、ルートのリストを取る:あなただけの財産onEnterに機能を設定する必要があり、そのために

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

私は、すべての依存関係を取得するために、トップのルータに私自身のハンドラを追加します。私はまた、いくつかの依存関係を必要とするルート上のカスタムプロパティを持って、私はその小道の名前はrequireとそれは単に約束を返す関数にすることができます。あなたの場合は、コンポーネントを使用してください。

このフォーカス取得時には、次のシグネチャを持つ関数を取る:

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); 
} 

あなたのニーズに合わせて、このコードを適応させることができます。その代わりにマップ関数を返すように変更してください。したがって、このライン

.map(({ require }) => require)

は、これは単なるアイデアです

.map(({ component }) => component.fetchData)

のようなものに変更されるだろう、私は貼り付けたコードは、Iセットアップのちょうど簡易版ですつかいます。私の現在の設定はReduxに縛られており、その例ではreduxに関するすべての参照を削除しようとしました。そのため、完全な意味がないのです。同形レンダリングも使用しているので、ハンドラはもう少し複雑で、依存関係が取得されるとすぐに再レンダリングが処理されるため、クライアントでコールバックは必要ありません。

しかし、あなたは基本的な考えを得る。あなたはonEnterフックで遊ぶ必要があります。そこでは、すべての依存関係を取得し、完了したらコールバック関数を呼び出すことができます。それはあなたの古い設定と同じですが、わずかに異なる方法で編成されています。

+0

ありがとうたくさんの@andre .. –

関連する問題