2015 年 7 月編集: 現在、不変性に基づく最も有望なフレームワークはReduxです。見てください!Om のようなカーソルは使用しません (Om Next もカーソルを使用しません)。
カーソルは実際にはスケーラブルではありません。以下で説明する CQRS の原則を使用しているにもかかわらず、依然としてコンポーネント内にあまりにも多くのボイラープレートが作成され、維持が難しく、既存のアプリ内でコンポーネントを移動するときに摩擦が生じます。
また、多くの開発者にとって、いつカーソルを使用するか使用しないかについて明確ではありません。また、使用すべきでない場所でカーソルを使用している開発者を見ているため、単純な小道具を使用するコンポーネントよりもコンポーネントが再利用しにくくなっています。
Redux は を使用しconnect()
、いつ使用するか (コンテナー コンポーネント)、いつ使用しないか (ステートレス/再利用可能なコンポーネント) を明確に説明します。カーソルをツリーに渡す定型的な問題を解決し、あまり妥協することなく優れたパフォーマンスを発揮します。
使わないデメリットについてはconnect()
こちらに書いています
もうカーソルを使用していないにもかかわらず、私の答えのほとんどの部分は有効なままです IMHO
スタートアップの内部フレームワークatom-reactで自分でやった
JS のいくつかの代替手段は、Morearty、React-cursors、OmniscientまたはBaobabです
当時はimmutable-js
まだありませんでした。私は移行を行わず、まだプレーンな JS オブジェクト (凍結) を使用していました。
頻繁に変更/コピーする非常に大きなリストがない限り、永続的なデータ構造ライブラリを使用する必要はないと思います。最適化としてパフォーマンスの問題に気付いたときにこれらのプロジェクトを使用できますが、Om の概念を活用して実装する必要はないようですshouldComponentUpdate
。興味深いことの 1 つは、ミューテーションのimmutable-js
バッチ処理に関する部分です。しかし、とにかく、それは最適化であり、Om のコンセプトを使用して React で非常にまともなパフォーマンスを得るための重要な前提条件ではないと思います。
オープンソース コードは次の場所にあります。
不変オブジェクト ( DeepFreezeで凍結) への交換可能な参照である Clojurescript Atomの概念があります。状態の複数の部分をアトミックに更新する場合に備えて、トランザクションの概念もあります。また、Atom の変更 (トランザクションの終了) をリッスンして、React レンダリングをトリガーすることができます。
Om のように (機能的なレンズのように)、cursorの概念があります。コンポーネントが状態をレンダリングできるようにするだけでなく、簡単に変更することもできます。これは、双方向のデータバインディングのためにカーソルに直接リンクできるため、フォームに便利です:
<input type="text" valueLink={this.linkCursor(myCursor)}/>
Omのように、箱から出して最適化された純粋なレンダリングの概念があります
Om との違い:
- ローカル状態なし (this.setState(o) 禁止)
Atom-React コンポーネントでは、ローカル コンポーネントの状態を持つことはできません。すべての状態は React の外に保存されます。既存の Js ライブラリを統合する必要がない限り (通常の React クラスを引き続き使用できます)、すべての状態を Atom に保存し (非同期/読み込み値であっても)、アプリ全体がメインの React コンポーネントから再レンダリングされます。React は、JSON 状態を DOM に変換する、非常に効率的な単なるテンプレート エンジンです。レンダリングごとに現在の Atom の状態をログに記録できるため、これは非常に便利です。レンダリング コードのデバッグは非常に簡単です。すぐに使用できるおかげでshouldComponentUpdate
、ユーザーがテキスト入力で新しいキーボード キーを押したり、マウスでボタンをホバーしたりするたびに、完全なアプリを再レンダリングすることさえできます。携帯でも!
- 状態を管理する独自の方法 (CQRS/EventSourcing および Flux に触発された)
Atom-React には、FluxとCQRSに触発された状態を管理するための非常に独断的な方法があります。React の外部にすべての状態を取得し、その JSON 状態を DOM に変換する効率的な方法を手に入れたら、残りの問題は JSON 状態を管理することであることがわかります。
発生したこれらの問題のいくつかは次のとおりです。
- 非同期値の処理方法
- DOM の変更を必要とする視覚効果を処理する方法 (マウスのホバーやフォーカスなど)
- 大規模なチームでスケールできるように状態を整理する方法
- ajax リクエストを発行する場所。
そこで、 Facebook Flux アーキテクチャに触発された Store の概念にたどり着きました。要点は、Flux ストアが実際に別のストアに依存する可能性があり、複雑なディスパッチャーを介してアクションを調整する必要があるという事実が、私は本当に嫌いだということです。そして、それらをレンダリングできるようにするには、複数のストアの状態を理解する必要があります。
Atom-React では、Store は、Atom が保持する状態内の単なる「予約された名前空間」です。
したがって、アプリケーションで発生したイベント ストリームからすべてのストアを更新することをお勧めします。各ストアは独立しており、他のストアのデータにはアクセスしません (コンポーネントがまったく同じイベントを受信し、異なるマシンでホストされ、必要に応じて独自の状態を管理する CQRS アーキテクチャとまったく同じです)。これにより、新しいコンポーネントを開発するときに 1 つのストアの状態だけを把握するだけでよいため、保守が容易になります。場合によっては複数のストアが同じデータを保持する必要があるため、これはどういうわけかデータの重複につながります (たとえば、SPA では、アプリの多くの場所で現在のユーザー ID が必要になる可能性があります)。しかし、2 つのストアが (イベントからの) 同じオブジェクトをその状態に置いた場合、これはまだ 1 つのオブジェクトであるため、実際には追加のデータを消費しません。
この選択の背後にある理由を理解するには、CQRS のリーダーである Udi Dahan やThe Fallacy Of ReUseなどの Autonomous Components に関するブログ記事を読むことができます。
したがって、ストアは、イベントを受け取り、Atom で名前空間の状態を更新する単なるコードです。
これにより、状態管理の複雑さが別のレイヤーに移動します。最も難しいのは、アプリケーション イベントを正確に定義することです。
このプロジェクトはまだ非常に不安定で、文書化されていないか、十分にテストされていないことに注意してください。しかし、私たちはすでにここでそれを使用して大きな成功を収めています。それについて議論したり貢献したりしたい場合は、IRC で私に連絡してくださいSebastien-L
: #reactjs
.
これが、このフレームワークで SPA を開発するという感覚です。デバッグモードでレンダリングされるたびに、次のものがあります。
- JSON を仮想 DOM に変換し、実際の DOM に適用するのにかかった時間。
- アプリのデバッグに役立つように記録された状態
- おかげで時間の無駄
React.addons.Perf
- 何が変更されたかを簡単に知るための、以前の状態と比較したパス差分
このスクリーンショットを確認してください:

この種のフレームワークがもたらすいくつかの利点については、まだ詳しく説明していません。
本当に元に戻す/やり直しが組み込まれています (これは、TodoMVC だけでなく、私の実際の運用アプリではそのままで機能しました)。ただし、私見では、多くのアプリのほとんどのアクションは実際にはサーバーに副作用をもたらしているため、UI を以前の状態に戻すことは常に意味があるとは限りません。以前の状態は古くなるからです。
状態のスナップショットを記録して、別のブラウザーに読み込むことができます。CircleCI は、このビデオでこれを実際に示しています。
ユーザー セッションの「ビデオ」を JSON 形式で記録し、バックエンド サーバーに送信してデバッグしたり、ビデオを再生したりできます。ユーザー セッションを別のブラウザーにライブ ストリーミングして、ユーザー支援を行うことができます (またはスパイして、ユーザーのライブ UX 動作を確認できます)。状態の送信は非常にコストがかかる可能性がありますが、おそらく Avro などの形式が役立ちます。または、アプリ イベント ストリームがシリアル化可能な場合は、それらのイベントを単純にストリーミングできます。私はすでにそれをフレームワークに簡単に実装しており、本番アプリで動作します(楽しみのために、まだバックエンドに何も送信していません)
ELMのようにタイムトラベリングデバッグが可能
興味のある方のために、「JSON でユーザー セッションを記録する」機能のビデオを作成しました。