web-dev-qa-db-ja.com

React + Fluxとサーバー側のレンダリング?(同形React + Flux)

同型アプリケーションでアプリの初期状態を設定する一般的な方法は何ですか? Fluxがなければ、私は次のようなものを単純に使用します。

_var props = { }; // initial state
var html = React.renderToString(MyComponent(props);
_

次に、そのマークアップを express-handlebars でレンダリングし、_{{{reactMarkup}}_で表示します。

クライアント側で初期状態を設定するには、次のようにします。

_if (typeof window !== 'undefined') {
    var props = JSON.parse(document.getElementById('props').innerHTML);
    React.render(MyComponent(props), document.getElementById('reactMarkup'));
}
_

つまり、本質的にはサーバーとクライアントで状態を2回設定していますが、Reactは違いを比較するため、ほとんどの場合、再レンダリングによるパフォーマンスへの影響はありません。


Fluxアーキテクチャにアクションとストアがある場合、この原則はどのように機能しますか?私のコンポーネントの中で私ができること:

_getInitialState: function() {
  return AppStore.getAppState();
}
_

しかし、サーバーからAppStoreの初期状態をどのように設定しますか?プロパティを渡さずに_React.renderToString_を使用すると、AppStore.getAppState()が呼び出されますが、サーバーのストアにどのように状態を設定するかわからないため、何も含まれていません。

2015年2月5日更新

Fluxible、Fluxxor、RefluxのようなサードパーティのFlux実装を使用しないクリーンなソリューションを探しています。

2016年8月19日更新

Redux を使用します。

42
Sahat Yalkabov

alt.js を使用する場合は、alt.bootstrapおよびalt.flushdocs )で実現できます。

私はフラックスの実装として、ノードのjsを反応サーバー側のレンダリングとalt.jsで使用しています。

これはどのように見えるかです:

var data = {}; // Get the data whatever you want and return it bootstrap ready.

// Reminder - renderToString is synchronised
var app = React.renderToString(
     AppFactory(data)
);

// In this point the react rendering was finished so we can flush the data and reset the stores

alt.flush();

私のapp.jsx

/**
 *
 */
componentWillMount: function () {

    // This beauty here is that componentWillMount is run on the server and the client so this is all we need to do. No need for other third-party isomorphic frameworks

    alt.bootstrap(
        JSON.stringify(this.props, null, 3)
    );

}
1
Rotem

dispatchr とyahooの関連ライブラリを見てください。

ほとんどのフラックス実装は、格納されたシングルトン、ディスパッチャー、およびアクションを使用するため、node.jsでは機能せず、htmlにレンダリングしてリクエストに応答するタイミングを知る必要がある「完了」の概念がありません。

FetchrやroutrなどのYahooのライブラリーは、非常に純粋な形式の依存性注入を使用することにより、このノードの制限を回避します(引数名などの解析関数はありません)。

代わりに、このようなAPI関数を services/todo.js で定義します。

create: function (req, resource, params, body, config, callback) {

そして actions/createTodo.js のこのようなアクション:

module.exports = function (context, payload, done) {
    var todoStore = context.getStore(TodoStore);
...
context.dispatch('CREATE_TODO_START', newTodo);
...
context.service.create('todo', newTodo, {}, function (err, todo) {

最後の行は、services/todo.jsのcreate関数を間接的に呼び出します。この場合、間接的には次のいずれかを意味します。

  • サーバー上:
    • サーバー上にいるときにフェッチャーが追加の引数を入力します
    • その後、コールバックを呼び出します
  • クライアント側:
    • フェッチャークライアントがhttpリクエストを行う
    • サーバー上のフェッチャーがそれをインターセプトします
    • 正しい引数でサービス関数を呼び出します
    • クライアントフェッチャーに応答を送信します
    • クライアント側フェッチャーがコールバックの呼び出しを処理します

これは氷山の一角にすぎません。これは非常に洗練されたモジュールのグループであり、一緒に動作して難しい問題を解決し、使用可能なAPIを提供します。同型は、実際の使用例では本質的に複雑です。これが、多くのフラックス実装がサーバー側レンダリングをサポートしない理由です。

また、fluxを使用しないことを検討することもできます。これはすべてのアプリケーションに意味があるわけではなく、しばしば邪魔になります。ほとんどの場合、必要な場合はアプリケーションのいくつかの部分でのみ必要です。プログラミングには特効薬はありません!

14
Brigand

FakeRainBrigandは正解です。サーバー側Fluxの最大の問題はシングルトンです。 Flummoxはシングルトンを使用しないことでこの問題を修正し、Fluxセットアップ全体を単一の再利用可能なクラスにカプセル化できるようにします。次に、リクエストごとに新しいインスタンスを作成します。 React Routerなどのルーティングソリューションと組み合わせると、完全に同型のアプリケーションを作成できます。

Flummoxを使用したくない場合でも、ソースは簡単に理解でき、自分で何かを作成するためのガイドとして使用できます。

https://github.com/acdlite/flummox

3
Andrew Clark

問題は、"Flux server rendering"を検索すると、すぐにこの質問にぶつかり、-Reux.jsコミュニティによって作成された Redux について言及されていないことです。rackt 。 Reduxの documentation サーバーレンダリングが重要な理由、HTML内の初期状態をクライアントに送信する必要がある理由(Fluxが不十分になる場所)とその方法そう。

0
Tommz