2016-12-13 17 views
1

非同期にフェッチされたデータに基づいて反応コンポーネントを初期状態にする方法がわかりました。 MyComponentはAPIからデータをフェッチし、その内部のdataプロパティをMobx actionで設定します。コンポーネントデータをMobxと非同期にサーバー側にロード

クライアント側では、componentDidMountが呼び出され、データが取得され、正しく設定されてレンダリングされます。

import React from 'react'; 
import { observer } from 'mobx-react'; 
import { observable, runInAction } from 'mobx'; 

@observer 
export default class MyComponent extends React.Component { 
    @observable data = []; 

    async fetchData() { 
     loadData() 
      .then(results => { 
       runInAction(() => { 
        this.data = results; 
       }); 
      }); 
    } 

    componentDidMount() { 
     this.fetchData(); 
    } 

    render() { 
     // Render this.data 
    } 
} 

私はサーバー上でcomponentDidMountが呼び出されていないことを理解しています。私は最初の店がProviderコンポーネントを介して計算され、渡され、多くの記事を見てきました

import React from 'react'; 
import { renderToString } from 'react-dom/server'; 
import { useStaticRendering } from 'mobx-react'; 
import { match, RouterContext } from 'react-router'; 
import { renderStatic } from 'glamor/server' 
import routes from './shared/routes'; 

useStaticRendering(true); 

app.get('*', (req, res) => { 
    match({ routes: routes, location: req.url }, (err, redirect, props) => { 
     if (err) { 
      console.log('Error', err); 
      res.status(500).send(err); 
     } 

     else if (redirect) { 
      res.redirect(302, redirect.pathname + redirect.search); 
     } 

     else if (props) { 
      const { html, css, ids } = renderStatic(() => renderToString(<RouterContext { ...props }/>)); 

      res.render('../build/index', { 
       html, 
       css 
      }); 
     } 

     else { 
      res.status(404).send('Not found'); 
     } 
    }) 
}) 

は、私は私のサーバーのためにこのようなものを持っています。私のコンポーネントはレンダリングされますが、状態は初期化されません。私はこのデータをストアに保持し、それをコンポーネントのローカルスコープにしたいと考えていません。どのようにそれを行うことができますか?

答えて

4

サーバー側のレンダリングでは、まずデータを取得してからレンダリングする必要があります。コンポーネントはSSRのライフサイクルを持たず、文字列にレンダリングするだけですが、将来の変更には対応できません。

データフェッチ方法は非同期であるため、コンポーネントが既に書き込まれているため、出力に影響することはありません。その答えは、最初にデータを取得してから、コンポーネントをマウントしてレンダリングし、その間に非同期メカニズム(約束、非同期など)を使用しないことです。私は、UIとデータフェッチロジックを分離することは、多くの理由(SSR、ルーティング、テスト)の良い練習であると考えています。this blogを参照してください。

もう1つの方法は、コンポーネントツリーを作成することですが、すべての約束が解決するまでシリアル化を待機します。それは例えばmobx-server-waitが使用するアプローチです。

+0

ストアを使用して初期化する以外に方法はありませんか? – Komo

+0

はい、あります。第2のリンクを参照してください – mweststrate

+0

ありがとう、私はhttps://github.com/ericclemmons/react-resolverを使用して2番目のアプローチを使用しました – Komo

関連する問題