2016-08-12 4 views
1

現在の設定では、マルチページユニバーサルWebアプリケーションを構築しています(サーバとクライアントの両方でルーティングするために反応ルータを使用しています)。このプロジェクトでは、(redux)ストアは使用していません(私は今は不必要と考えています)。普遍的なReactJSで二重APIフェッチを解決する方法

componentWillMountメソッド内で実行されるリモートAPIからデータを取得するコンポーネントの1つです。

サーバーでレンダリングすると、コンポーネントはデータをフェッチし、レンダリングし、レンダリングしたHTMLをクライアントに送信します。

クライアントがReactJSでHTMLをマウントすると、componentWillMountメソッドから再度データをフェッチします。それが不必要なダブルデータフェッチを引き起こします。

解決策はありますか?

答えて

0

あなたのデータはすでに存在しているので、サーバーとcomponentDidMount(あなたはcomponentWillMountでajax呼び出しを行うはずがありません)の両方で呼び出すことができる条件付きフェッチを行う関数が必要です。

例えば、このコンポーネントはReduxのを使用して私のためにどのように見えるかです:

class User extends Component { 

    static readyOnActions(dispatch, params) { 
    return Promise.all([ 
     dispatch(UserActions.fetchUserIfNeeded(params.id)) 
    ]); 
    } 

    componentDidMount() { 
    User.readyOnActions(this.props.dispatch, this.props.params); 
    } 

これは現在のページであれば、サーバはreadyOnActionsを呼び出します、そしてクライアントcomponentDidMountに同じことを呼び出すことができます - fetchUserIfNeededというアクションは、サーバーがまだデータが存在するかどうかをチェックしていない場合にのみAJAXリクエストを行います(有効であるかどうかなどのチェックを追加できます。

0

Dominic Tobiasからのお返事ありがとうございます。

私はカップルのソリューションを開発しようとしましたが、私はそれが私に適していることを発見しました。

class PageContainer extends Component { 
    static fetchData(params) { 
     return fetch('...URL...') 
    } 

    render() { 
     const {data} = this.props; 
     //render logic here 
    } 
} 

とサーバ側の

PageContainer.fetchDataを呼び出すとまで待つ:

まず、私はこのようなPromiseを返す静的メソッド呼び出しfetchDataをいずれかcomponentWillMountまたはコンポーネント内componentDidMountでデータをフェッチするが、作成しないことに決めました約束は、果たさPageContainerpropsとしてデータを渡し、この

<html> 
    <head></head> 
    <body> 
     <div id="roor">{..react rendered HTML..}</div> 
     <script>window.__DATA__ = {..data..}</script> 
    </body> 
</html> 

のような水和したデータをHTMLをレンダリングしています私が言ったように、このアプリのために、私は今還元は不要だと思う。

次に、クライアント側のルーティングには、react-routerが非同期データをロードできないという問題があります。それを修正するために、私はAsyncPropsを探しに行き、AsyncCompと呼ばれる自分の小さなバージョンを書きました。

const Root = <Router history={browserHistory} routes={routes} render={(props) => <AsyncComp {...props} data={window.__DATA__}/>}/> 
ReactDOM.render(Root, document.getElementById("root")); 

すべてですそれ:あなたはこのようreact-routerとクライアント側上で反応ブートストラップすることができます。

PS。 AsyncCompを作成した後、次のようにサーバー側で使用することもできます。

関連する問題