Redux: 非同期アクションへの代替アプローチ

作成日 2015年12月27日  ·  44コメント  ·  ソース: reduxjs/redux

私は非同期アクションがreduxで行われる方法の代替案を模索してきましたが、私が行ったことについて他の人からのコメントをいただければ幸いです。

私のアプローチを説明するために、reduxのクローンの非同期の例を変更しました: https

通常、外部アクションは、アクション作成者を非同期にすることによって実行されます。 非同期の例の場合、fetchPostsアクションの作成者はREQUEST_POSTSアクションをディスパッチしてリクエストの開始を示し、投稿がAPIから戻ってきたらRECEIVE_POSTSをディスパッチします。

私の例では、すべてのアクション作成者が同期しています。 代わりに、状態に基づいて現在実行されているはずの非同期アクションのリストを返す関数があります。 ここで私の例を参照してください: https ://github.com/rackt/redux/compare/master ... winstonewert:master#diff-8a94dc7aa7bdc6e5390c9216a69761f8R12

doReactions関数はストアをサブスクライブし、現在行われている要求の実際の状態が、要求を開始またはキャンセルすることによってdoReactions状態によって返される状態と一致することを確認します。

では、違いは何ですか?

1)反応関数は状態の純粋関数です。 これにより、テストが簡単になります。
2)要求を行う実際のロジックはより単純です。 以前のコンテナやアクションクリエーターに広がっていたさまざまなロジックとは対照的に、私の例のいくつかのライン関数を参照してください。
3)リクエストのキャンセルが簡単になります。

何かご意見は?

discussion feedback wanted

最も参考になるコメント

私もreduxで副作用を処理する別の方法について多くのことを考えてきました。現在のアプローチで見られる問題のいくつかと、その理由と方法を頭に入れて、スレッドをハイジャックしないことを願っています。その明らかな単純さにもかかわらず、正しい方向への大きな一歩。

アクションクリエーターの副作用の問題

純粋関数型言語では、副作用は常にアプリケーションの端まで持ち上げられ、実行のためにランタイムに戻されます。 Elmでは、レデューサーは新しい状態と実行する必要のあるエフェクトを含むタプルを返します。 ただし、このシグネチャを持つメソッドは、他のreduxレデューサーとはまだ構成できません。

reduxで副作用を実行するための明白な(しかしおそらく最良ではない)場所はアクションクリエーターになり、このパターンをサポートするためにいくつかの異なるミドルウェアオプションが開発されました。 ただし、現在のミドルウェアアプローチは、レデューサーのファーストクラスの概念として副作用を返すことができないための回避策であると思います。

人々はまだreduxで素晴らしいものを構築しており、その大きな前進と、ほとんどの選択肢よりもはるかにシンプルで実用的ですが、アクションクリエーターの内部に副作用があることにはいくつかの問題があります。

  • 暗黙の状態は非表示になります
  • ビジネスロジックの複製
  • コンテキストの仮定や依存関係により、再利用性が低下します
  • 副作用のあるアクションクリエーターはテストが難しい
  • 最適化またはバッチ処理できません

暗黙の状態は非表示になります

カウンターアプリケーションでは、incrementAsyncがタイムアウトを作成し、その完了時にのみアプリケーションの状態が更新されます。 たとえば、インクリメント操作が進行中であることを視覚的に示すインジケーターを表示したい場合、ビューはアプリケーションの状態からこれを推測できません。 この状態は暗黙的で非表示です。

エレガントなこともありますが、暗黙の状態が隠されており、簡単にシリアル化できないため、ジェネレーターをアクションクリエーターのオーケストレーターとして使用するという提案についてはよくわかりません。

redux-thunkなどを使用すると、インクリメント操作が開始されたときと完了したときに通知する複数のメッセージをレデューサーにディスパッチできますが、これにより別の一連の問題が発生します。

エフェクトの完了後にインクリメント操作が進行中であるとマークされるポイントに状態を巻き戻すと、実際には副作用が再生されないため、無期限に進行し続けます。

あなたの提案はこの問題を解決しているようです。 副作用は状態から作成されるため、意図は何らかの形で結果の状態で表現される必要があります。したがって、ストアをアクションが開始される前の状態に戻すと、反応はではなく、効果を再び開始します。状態を不安定なままにします。

ビジネスロジックの複製

アプリケーションが特定の状態にある場合にのみ、アクションが副作用を生成するのは自然なことです。 reduxでは、アクション作成者が状態を必要とする場合、それは単純で純粋な関数であるか、状態を明示的に提供する必要があります。

簡単な例として、サンプルのカウンターアプリケーションから始めて、カウンターが5の倍数になるたびにカウンターをランダムなフォントの色に変更したいとします。

乱数の生成は不純であるため、この動作を配置するための推奨される場所はアクション作成者です。 ただし、counter、increment、decrement、incrementAsync、incrementIfOdd(この場合は変更する必要はありません)の値を変更できるいくつかの異なるアクションがあります。

インクリメントとデクリメントは、以前はレデューサーで処理されていたため、現在の値にアクセスできるため、以前は状態を必要としませんでしたが、レデューサーは副作用(乱数生成)を持たないか返すことができないため、これらの関数は、必要な不純なアクション作成者になります。現在のカウンター値を知って、新しいランダムなフォントの色を選択する必要があるかどうかを判断し、このロジックをすべてのカウンターアクション作成者に複製する必要があります。

現在の状態を明示的に提供する代わりに考えられる方法の1つは、redux-thunkを使用し、コールバックを返して現在の状態にアクセスすることです。 これにより、現在の値を提供するためにアクションが作成されるすべての場所を変更する必要がなくなりますが、アクションの作成者は、グローバルアプリケーションの状態のどこに値が格納されているかを知る必要があり、同じカウンターを何度も再利用する機能が制限されます。同じアプリケーション、または状態が異なる構造になっている可能性のある異なるアプリケーション。

コンテキストの仮定や依存関係により、再利用性が低下します

カウンターの例をもう一度見てみると、カウンターインスタンスが1つしかないことに気付くでしょう。 同じ状態を表示/更新する多くのカウンターをページに配置するのは簡単ですが、各カウンターで異なる状態を使用する場合は、カウンターに追加の変更を加える必要があります。

これは、レデューサーおよびコンポーネントエンハンサーとしてジェネリックリストを作成する方法の前に説明されてい

カウンターが単純なアクションタイプのみを使用する場合、 elmアーキテクチャを適用するのは比較的簡単です。

この場合、親はアクションクリエーターまたはディスパッチャーをラップして、必要なコンテキストでメッセージを拡張するだけで、ローカライズされた状態でレデューサーを直接呼び出すことができます。

React Elmishの例は印象的ですが、特に問題のある2つのアクション作成者incrementIfOddとincrementAsyncが例から欠落しています。

incrementalIfOddは、現在の状態を判別するためにミドルウェアに依存しているため、アプリケーション状態内でのその位置を知る必要があります。

通常、incrementAsyncは、親コンポーネントに公開されていないため、追加のコンテキストでラップできない増分アクションを直接ディスパッチします。

あなたの提案はこの問題に直接対処していませんが、incrementAsyncが状態を{counter: 0, incrementAfterDelay: 1000}に変更してストアリスナーの副作用をトリガーする単純なアクションとして実装された場合、incrementAsyncは単純なメッセージになります。 増分IfOddは純粋であるため、レデューサーに実装することも、状態を明示的に提供することもできます。したがって、必要に応じてelmアーキテクチャを再度適用することが可能になります。

副作用のあるアクションクリエーターはテストが難しい

これは、副作用のテストがより困難になることは明らかだと思います。 副作用が現在の状態とビジネスロジックを条件とするようになると、それらはより困難になるだけでなく、テストすることもより重要になります。

あなたの提案は、状態遷移が実際にそれらのどれも実行することなく、望ましい反応を含む状態を作成するというテストを簡単に作成することを可能にします。 反応は、条件付き状態やビジネスロジックを必要としないため、テストも簡単です。

最適化またはバッチ処理できません

John A De Goesからの最近のブログ投稿では、効果を表現するためのIOやタスクなどの不透明(OPAQUE)型の問題について説明しています。 不透明(OPAQUE)型ではなく、副作用の宣言型の説明を使用することで、後で効果を最適化または組み合わせることができます。

FPのモダンアーキテクチャ

サンク、プロミス、ジェネレーターは不透明であるため、重複するAPI呼び出しのバッチ処理や抑制などの最適化は、 fetchPostsIfNeededと同様の関数で明示的に処理する必要があります。

あなたの提案はfetchPostsIfNeededを排除し、複数のリクエストを最適化したり、要求されたデータが多かれ少なかれ必要に応じて異なるAPIのセットを使用したりできるreactions関数を実装することは完全に実行可能と思われます。

私の実装

最近、reduxのフォークを作成しました。これにより、現在のように新しい状態だけを返すレデューサー、または新しい状態とレデューサーの後に実行するエフェクトの説明を含むEffectsを含む特別なオブジェクトを作成できます。

既存のレデューサーコードとの互換性を維持するために、composeおよびcombineReducersを変更して既存のレデューサーよりも効果を上げる必要があったため、reduxをフォークせずにこれを行う方法がわかりませんでした。

ただし、あなたの提案は、reduxを変更する必要がないという点で非常に優れています。 さらに、あなたのソリューションは、暗黙の隠れた状態の問題を解決する上でより良い仕事をし、おそらく結果として生じる反応を組み合わせたり最適化したりするのが簡単だと思います。

概要

Reactが「単なるUI」であり、アプリケーションの状態を実際に保存または更新する方法をあまり規定していないのと同じように、Reduxはほとんど「ただのストア」​​であり、副作用の処理方法についてはあまり規範的ではありません。

実用的で物事を成し遂げたことで誰かを責めることは決してありません。reduxとミドルウェアへの多くの貢献者は、人々が以前よりも速くそしてより良いものを作ることを可能にしました。 私たちがこれまでに得たのは、彼らの貢献からのみです。 貢献してくれたすべての人に感謝します。

Reduxは素晴らしいです。 これらはRedux自体に必要な問題ではありませんが、現在のアーキテクチャパターンと、状態の変更前ではなく後のエフェクトを実行する動機と潜在的な利点に対する建設的な批判があれば幸いです。

全てのコメント44件

面白いアプローチ! XHRの実行に使用される方法のように、非同期の性質から切り離すのが理想的であるように思われます。あるいは、そもそもWebリクエストが非同期の原因であるようです。

私もreduxで副作用を処理する別の方法について多くのことを考えてきました。現在のアプローチで見られる問題のいくつかと、その理由と方法を頭に入れて、スレッドをハイジャックしないことを願っています。その明らかな単純さにもかかわらず、正しい方向への大きな一歩。

アクションクリエーターの副作用の問題

純粋関数型言語では、副作用は常にアプリケーションの端まで持ち上げられ、実行のためにランタイムに戻されます。 Elmでは、レデューサーは新しい状態と実行する必要のあるエフェクトを含むタプルを返します。 ただし、このシグネチャを持つメソッドは、他のreduxレデューサーとはまだ構成できません。

reduxで副作用を実行するための明白な(しかしおそらく最良ではない)場所はアクションクリエーターになり、このパターンをサポートするためにいくつかの異なるミドルウェアオプションが開発されました。 ただし、現在のミドルウェアアプローチは、レデューサーのファーストクラスの概念として副作用を返すことができないための回避策であると思います。

人々はまだreduxで素晴らしいものを構築しており、その大きな前進と、ほとんどの選択肢よりもはるかにシンプルで実用的ですが、アクションクリエーターの内部に副作用があることにはいくつかの問題があります。

  • 暗黙の状態は非表示になります
  • ビジネスロジックの複製
  • コンテキストの仮定や依存関係により、再利用性が低下します
  • 副作用のあるアクションクリエーターはテストが難しい
  • 最適化またはバッチ処理できません

暗黙の状態は非表示になります

カウンターアプリケーションでは、incrementAsyncがタイムアウトを作成し、その完了時にのみアプリケーションの状態が更新されます。 たとえば、インクリメント操作が進行中であることを視覚的に示すインジケーターを表示したい場合、ビューはアプリケーションの状態からこれを推測できません。 この状態は暗黙的で非表示です。

エレガントなこともありますが、暗黙の状態が隠されており、簡単にシリアル化できないため、ジェネレーターをアクションクリエーターのオーケストレーターとして使用するという提案についてはよくわかりません。

redux-thunkなどを使用すると、インクリメント操作が開始されたときと完了したときに通知する複数のメッセージをレデューサーにディスパッチできますが、これにより別の一連の問題が発生します。

エフェクトの完了後にインクリメント操作が進行中であるとマークされるポイントに状態を巻き戻すと、実際には副作用が再生されないため、無期限に進行し続けます。

あなたの提案はこの問題を解決しているようです。 副作用は状態から作成されるため、意図は何らかの形で結果の状態で表現される必要があります。したがって、ストアをアクションが開始される前の状態に戻すと、反応はではなく、効果を再び開始します。状態を不安定なままにします。

ビジネスロジックの複製

アプリケーションが特定の状態にある場合にのみ、アクションが副作用を生成するのは自然なことです。 reduxでは、アクション作成者が状態を必要とする場合、それは単純で純粋な関数であるか、状態を明示的に提供する必要があります。

簡単な例として、サンプルのカウンターアプリケーションから始めて、カウンターが5の倍数になるたびにカウンターをランダムなフォントの色に変更したいとします。

乱数の生成は不純であるため、この動作を配置するための推奨される場所はアクション作成者です。 ただし、counter、increment、decrement、incrementAsync、incrementIfOdd(この場合は変更する必要はありません)の値を変更できるいくつかの異なるアクションがあります。

インクリメントとデクリメントは、以前はレデューサーで処理されていたため、現在の値にアクセスできるため、以前は状態を必要としませんでしたが、レデューサーは副作用(乱数生成)を持たないか返すことができないため、これらの関数は、必要な不純なアクション作成者になります。現在のカウンター値を知って、新しいランダムなフォントの色を選択する必要があるかどうかを判断し、このロジックをすべてのカウンターアクション作成者に複製する必要があります。

現在の状態を明示的に提供する代わりに考えられる方法の1つは、redux-thunkを使用し、コールバックを返して現在の状態にアクセスすることです。 これにより、現在の値を提供するためにアクションが作成されるすべての場所を変更する必要がなくなりますが、アクションの作成者は、グローバルアプリケーションの状態のどこに値が格納されているかを知る必要があり、同じカウンターを何度も再利用する機能が制限されます。同じアプリケーション、または状態が異なる構造になっている可能性のある異なるアプリケーション。

コンテキストの仮定や依存関係により、再利用性が低下します

カウンターの例をもう一度見てみると、カウンターインスタンスが1つしかないことに気付くでしょう。 同じ状態を表示/更新する多くのカウンターをページに配置するのは簡単ですが、各カウンターで異なる状態を使用する場合は、カウンターに追加の変更を加える必要があります。

これは、レデューサーおよびコンポーネントエンハンサーとしてジェネリックリストを作成する方法の前に説明されてい

カウンターが単純なアクションタイプのみを使用する場合、 elmアーキテクチャを適用するのは比較的簡単です。

この場合、親はアクションクリエーターまたはディスパッチャーをラップして、必要なコンテキストでメッセージを拡張するだけで、ローカライズされた状態でレデューサーを直接呼び出すことができます。

React Elmishの例は印象的ですが、特に問題のある2つのアクション作成者incrementIfOddとincrementAsyncが例から欠落しています。

incrementalIfOddは、現在の状態を判別するためにミドルウェアに依存しているため、アプリケーション状態内でのその位置を知る必要があります。

通常、incrementAsyncは、親コンポーネントに公開されていないため、追加のコンテキストでラップできない増分アクションを直接ディスパッチします。

あなたの提案はこの問題に直接対処していませんが、incrementAsyncが状態を{counter: 0, incrementAfterDelay: 1000}に変更してストアリスナーの副作用をトリガーする単純なアクションとして実装された場合、incrementAsyncは単純なメッセージになります。 増分IfOddは純粋であるため、レデューサーに実装することも、状態を明示的に提供することもできます。したがって、必要に応じてelmアーキテクチャを再度適用することが可能になります。

副作用のあるアクションクリエーターはテストが難しい

これは、副作用のテストがより困難になることは明らかだと思います。 副作用が現在の状態とビジネスロジックを条件とするようになると、それらはより困難になるだけでなく、テストすることもより重要になります。

あなたの提案は、状態遷移が実際にそれらのどれも実行することなく、望ましい反応を含む状態を作成するというテストを簡単に作成することを可能にします。 反応は、条件付き状態やビジネスロジックを必要としないため、テストも簡単です。

最適化またはバッチ処理できません

John A De Goesからの最近のブログ投稿では、効果を表現するためのIOやタスクなどの不透明(OPAQUE)型の問題について説明しています。 不透明(OPAQUE)型ではなく、副作用の宣言型の説明を使用することで、後で効果を最適化または組み合わせることができます。

FPのモダンアーキテクチャ

サンク、プロミス、ジェネレーターは不透明であるため、重複するAPI呼び出しのバッチ処理や抑制などの最適化は、 fetchPostsIfNeededと同様の関数で明示的に処理する必要があります。

あなたの提案はfetchPostsIfNeededを排除し、複数のリクエストを最適化したり、要求されたデータが多かれ少なかれ必要に応じて異なるAPIのセットを使用したりできるreactions関数を実装することは完全に実行可能と思われます。

私の実装

最近、reduxのフォークを作成しました。これにより、現在のように新しい状態だけを返すレデューサー、または新しい状態とレデューサーの後に実行するエフェクトの説明を含むEffectsを含む特別なオブジェクトを作成できます。

既存のレデューサーコードとの互換性を維持するために、composeおよびcombineReducersを変更して既存のレデューサーよりも効果を上げる必要があったため、reduxをフォークせずにこれを行う方法がわかりませんでした。

ただし、あなたの提案は、reduxを変更する必要がないという点で非常に優れています。 さらに、あなたのソリューションは、暗黙の隠れた状態の問題を解決する上でより良い仕事をし、おそらく結果として生じる反応を組み合わせたり最適化したりするのが簡単だと思います。

概要

Reactが「単なるUI」であり、アプリケーションの状態を実際に保存または更新する方法をあまり規定していないのと同じように、Reduxはほとんど「ただのストア」​​であり、副作用の処理方法についてはあまり規範的ではありません。

実用的で物事を成し遂げたことで誰かを責めることは決してありません。reduxとミドルウェアへの多くの貢献者は、人々が以前よりも速くそしてより良いものを作ることを可能にしました。 私たちがこれまでに得たのは、彼らの貢献からのみです。 貢献してくれたすべての人に感謝します。

Reduxは素晴らしいです。 これらはRedux自体に必要な問題ではありませんが、現在のアーキテクチャパターンと、状態の変更前ではなく後のエフェクトを実行する動機と潜在的な利点に対する建設的な批判があれば幸いです。

このアプローチとredux-sagaの違いを理解しようとしています。 最初は同じことをしているように見えるので、ジェネレーターの状態を暗黙的に隠すという主張に興味があります。 しかし、それはio.take実装方法に依存するかもしれないと思います。 佐賀がそのyieldで現在ブロックされている場合にのみアクションを処理する場合、私はあなたが何を意味するのかをはっきりと理解しています。 しかし、redux-sagaがio.takeが過去のアクションを返すようにアクションをキューに入れる場合、同じことをしているように見えます。 いずれにせよ、アクションストリームをリッスンすることでトリガーされ、非同期でdispatchアクションを実行できるロジックがあります。

しかし、それは興味深い概念です。 Reduxをアクションストリームとして概念化し、そこから状態遷移と効果がトリガーされます。 それは、単にそれを状態プロセッサと見なすのではなく、別の見方であるように私には思えます。

イベントソーシングモデルでは、Reduxアクションが「コマンド」(アクションを実行するための偶発的なリクエスト)であるか、「イベント」(状態のアトミック遷移、フラットビューに反映される)であるかということになると思います。 どちらの方法でも考えられるほど柔軟なツールがあると思います。

私も「スマートアクションクリエーター」の現状に少し不満がありますが、別の方法でアプローチしてきました。Reduxはイベントストアであり、アクションは多くの可能な効果の1つです。外部の「コントローラー」レイヤーによってトリガーされる可能性があります。 私はこのアプローチに従ったコードをreact-redux-controllerに分解しましたが、これを達成するための潜在的に軽量な方法については中途半端な考えを念頭に置いています。 ただし、react-reduxには、現在持っていないフックが必要であり、一部のストアラッピングハイジンクはまだうまく機能していません。

https://github.com/rackt/redux/issues/1200で説明されているストアhijinks

このアプローチとredux-sagaの違いを理解しようとしています

私は自分のアプローチを思いついた後までredux-sagaを見ませんでしたが、確かにいくつかの類似点があります。 しかし、私はまだいくつかの違いがあります:

  1. 私のアプローチでは、アクションストリームにアクセスできず、状態にのみアクセスできます。 redux-sagaは、アクションがあったという理由だけでプロセスを開始できます。 私のアプローチでは、レデューサーが状態を変更して、リアクション関数をトリガーしてアクションを要求する必要があります。
  2. 私のアプローチでは、すべての状態がreduxの状態で存在する必要があります。 Redux-sagaには、sagaジェネレーター(どの行にあるか、ローカル変数の値)に存在する追加の状態があります。
  3. 私のアプローチは非同期部分を分離します。 反応の実際のロジックは、非同期機能を処理せずにテストできます。 佐賀はこれらをまとめています。
  4. 物語は、同じ論理のさまざまな部分をまとめます。 私のアプローチでは、サガをレデューサー、リアクション、およびリアクションタイプの実装に属する部分に分割する必要があります。

基本的に、私のアプローチは純粋関数を強調し、すべてをredux状態に保ちます。 redux-sagaのアプローチは、より表現力豊かであることを強調しています。 長所と短所があると思いますが、私は私の方が好きです。 しかし、私は偏見があります。

それは本当に有望に聞こえます。 反応機構をドメインロジックから切り離す例を見る方が説得力があると思います。

あなたの提案はfetchPostsIfNeededを排除し、複数のリクエストを最適化したり、要求されたデータが多かれ少なかれ必要に応じて異なるAPIのセットを使用したりできるリアクション関数を実装することは完全に実行可能と思われます。

現状では、リアクション関数では実際にはそれを行うことができませんでした。 そこにあるロジックは、どのアクションがすでに開始されているかを知る必要があります(これ以上バッチ処理することはできません)が、リアクション関数には情報がありません。 反応()関数を消費する反応機構は確かにそれらのことを行うことができます。

反応機構をドメインロジックから切り離す例を見る方が説得力があると思います。

doReactions()関数がXMLHttpRequestの開始/停止を処理する方法を意味していると思いますか? 私はそれを行うためのさまざまな方法を模索してきました。 問題は、2つの反応が実際に同じ反応であるかどうかを検出する一般的な方法を見つけるのが難しいことです。 LodashのisEqualはほぼ機能しますが、クロージャでは失敗します。

doReactions()関数がXMLHttpRequestの開始/停止を処理する方法を意味していると思いますか?

いいえ、私はあなたの例では、反応の概念を設定するためのすべての構成が、どのデータがフェッチされているかというドメインロジック、およびそのデータがどのようにフェッチされているかの詳細と混合されていることを意味します。 一般的な側面は、例に固有の詳細とあまり結びついていないものに考慮されるべきであるように私には思えます。

いいえ、私はあなたの例では、反応の概念を設定するためのすべての構成が、どのデータがフェッチされているかというドメインロジック、およびそのデータがどのようにフェッチされているかの詳細と混合されていることを意味します。 一般的な側面は、例に固有の詳細とあまり結びついていないものに考慮されるべきであるように私には思えます。

うーん...ドメインロジックで同じことを意味するわけではないと思います。

私の見方では、reactions()関数はドメインロジックをカプセル化し、リアクションの適用方法のロジックを処理するdoReactions()関数とは別のものです。 しかし、あなたは何か違うことを意味しているようです...

現状では、リアクション関数では実際にはそれを行うことができませんでした。 そこにあるロジックは、どのアクションがすでに開始されているかを知る必要があります(これ以上バッチ処理することはできません)が、リアクション関数には情報がありません。 反応()関数を消費する反応機構は確かにそれらのことを行うことができます。

私は主に、単一のイベントが状態変化を引き起こし、複数のコンポーネントが同じ情報を要求した場合、それらを最適化できる可能性があることを意味しました。 ただし、以前の状態変化による副作用がまだ保留中であるかどうかを判断するだけでは不十分であるため、追加の要求は不要です。

最初は、すべての状態をアプリの状態に保つことができると考えていましたが、最近のストップウォッチの問題について考え始めたとき、ストップウォッチisOnをアプリケーションの状態に保存する必要がある一方で、実際のintervalこのストップウォッチに関連付けられているisOnはアプリの状態である必要がありますが、この場合、それだけでは十分な状態ではありません。

私は主に、単一のイベントが状態変化を引き起こし、複数のコンポーネントが同じ情報を要求した場合、それらを最適化できる可能性があることを意味しました。 ただし、以前の状態変化による副作用がまだ保留中であるかどうかを判断するだけでは不十分であるため、追加の要求は不要です。

リクエストをマージまたはバッチ処理することを考えていました。 重複を排除することは問題なく機能するはずです。 実際には、サーバーの応答が返されるまでリアクション関数から返される(したがって重複排除される)ため、保留中の状態変更の場合も問題なく処理する必要があります。

最初はすべての状態をアプリの状態に保つことができると思っていましたが、最近のストップウォッチの問題について考え始めたとき、ストップウォッチがOnであるという事実はアプリケーションの状態に保存する必要がある一方で、このストップウォッチに関連付けられている実際のインターバルオブジェクトに気付きました別の場所に保管する必要があります。 isOnはアプリの状態である必要がありますが、この場合、isOnだけでは十分な状態ではありません。

私の考えでは、現在保留中のリアクションは、リアクションコンポーネントのようなものです。 技術的には内部状態がありますが、現在の状態の関数としてモデル化します。

うーん...ドメインロジックで同じことを意味するわけではないと思います。

私の見方では、reactions()関数はドメインロジックをカプセル化し、リアクションの適用方法のロジックを処理するdoReactions()関数とは別のものです。 しかし、あなたは何か違うことを意味しているようです...

/reactions/indexモジュール全体を全体として取り上げましたが、そうです、 reactions関数は純粋にドメインロジックであることに同意します。 ただし、ドメイン固有のモジュールではなく、 doReactions定型文と一緒にラップされています。 それはあなたの方法論をノックすることではありません、それはライブラリコードとアプリコードの間の分離を一目で理解することを難しくするだけです。

次に、 doReactions自体は、APIからデータをフェッチする特定の行為の特定のメソッドにかなり緊密に結合されているように見えます。 肉付けされたリアクションライブラリは、さまざまなタイプのエフェクトのハンドラーを登録する方法かもしれないと思います。

それはあなたの方法をノックすることではありません。 このアプローチは本当に魅力的だと思います。

ほとんどの反応状態は、反応コンポーネントの状態が良い例えであるかどうかはわかりません
アプリの状態である必要がありますが、どうやら何らかの方法が必要です
に配置できないディスパッチイベント間の状態を維持するため
お店。

この種の状態は、 @ yelouafiが制御状態と
おそらくsagasは、シリアル化できない状態をモデル化するための適切な方法です。
独立したオブザーバー/アクターとしてのシステム。

サガなら隠されたサガの状態は気にならないと思います
ユーザーではなく、アプリケーションで生成されたイベント(リアクション)にのみ応答しました
開始されたイベント(アクション)。これにより、アプリレデューサーは
現在の状態と、条件付きのビジネスロジックを使用して
アプリケーションは、重複することなく、目的の副作用を許容する必要があります
ビジネスの論理。
17:56ウィンストンエバートで月、2016年1月4日には[email protected]
書きました:

私は主に、単一のイベントが状態変化を引き起こした場合、
複数のコンポーネントが同じ情報を要求した場合、それが可能になる可能性があります
それらを最適化します。 あなたは正しいですが、それ自体では十分ではありません
以前の状態変化による副作用がまだ保留中であるかどうかを判断します
したがって、追加の要求は不要です。

リクエストをマージまたはバッチ処理することを考えていました。 重複の排除
正常に動作するはずです。 実際には、保留状態の場合を処理する必要があります
変更は引き続き問題なく返されるため、変更も問題ありません。
サーバーの応答まで、反応は機能します(したがって、重複排除されます)
戻ってくる。

私は当初、アプリ内ですべての状態を維持できるのではないかと考えていました
状態ですが、最近のストップウォッチの問題について考え始めたとき、私は
ストップウォッチがオンであるという事実はに保存されるべきであることに気づきました
アプリケーションは、これに関連付けられた実際の間隔オブジェクトを示します
ストップウォッチは別の場所に保管する必要があります。 isOnはアプリ内にある必要があります
この場合、状態は単独ではありませんが十分な状態ではありません。

私の考えでは、現在保留中の反応はあなたのようなものです
コンポーネントを反応させます。 技術的には内部状態がありますが、モデル化しています
それらは現在の状態の関数として。


このメールに直接返信するか、GitHubで表示してください
https://github.com/rackt/redux/issues/1182#issuecomment-168858051

それはあなたの方法論をノックすることではありません、それはライブラリコードとアプリコードの間の分離を一目で理解することを難しくするだけです。

それは完全に公平です。

次に、doReactions自体は、APIからデータをフェッチする特定の行為の特定のメソッドとかなり緊密に結合されているように見えます。 肉付けされたリアクションライブラリは、さまざまなタイプのエフェクトのハンドラーを登録する方法かもしれないと思います。

はい。 私はまだそれを分割するための最良の方法を見つけようとしています。 等価性チェックの問題によって複雑になっています。

ほとんどの反応状態は、反応コンポーネントの状態が良い例えであるかどうかはわかりません
アプリの状態である必要がありますが、どうやら何らかの方法が必要です
に配置できないディスパッチイベント間の状態を維持するため
お店。

申し訳ありませんが、私はアナロジーを台無しにしたと思います。 私のポイントは、DOMの状態ほど、外部アクションの状態をコンポーネントの状態に反応させるために比較することではありません。 間隔またはXMLHttpRequestは、反応して作成および破棄するDOM要素に似ています。 あなたは単に現在のDOMがどうあるべきかを反応させてそれを実現させるだけです。 同様に、現在の外部反応のセットを返すだけで、フレームワークはそれを真にするためにアクションをキャンセルまたは開始します。

そのアプローチも本当に面白いと思います。 異なる状態マッピングをとる複数のdoReactionsを使用することを検討しましたか? 再利用可能なドライバーを作成できるcyclejsに似ていると思います。

function main(action$) {
  const state$ = action$.startWith(INITIAL_STATE).scan(reducer);

  return { 
    DOM: state$.map(describeDOM),
    HTTP: state$.map(describeRequests),
    ...
  };
}

1つの違いは、アクションストリームを取得するためにドライバーにイベントを照会せず( const someEvent$ = sources.DOM.select('.class').events('click') )、HTTPリクエストに対して行ったようにシンク内のアクションを直接指定する( <button onClick={() => dispatch(action())} /> )ことです。同様に。

Reactのアナロジーはかなりうまくいくと思います。 ただし、DOMを内部状態とは見なしませんが、内部状態はコンポーネントインスタンスと仮想DOMで構成されているのに対し、それが機能するAPIと見なします。

APIのアイデアは次のとおりです(Reactを使用。HTTPもこのように構築できます)。

// usage
const describe = (state, dispatch) => <MyComponent state={state} dispatch={dispatch} />;
const driver = createReactDOMDriver({ container } /* opts */);
store.subscribe(() => driver.update(describe(store.getState(), store.dispatch)); 
// (could be simplified further to eg. `store.use(driver, describe)` )

// implementation
const createReactDOMDriver = ({ container }) => {
  return {
    update: (element) => ReactDOM.render(element, container),
    destroy: () => ReactDOM.unmountComponentAtNode(container),
  };
};

describe getState (状態のスナップショットではなく) dispatch取得させます。 そうすれば、必要に応じて非同期にすることができます。

異なる状態マッピングをとる複数のdoReactionsを使用することを検討しましたか?

私はそれについて簡単に考えていました、そして私は今それについて少し行ったり来たりしています。 DOM用、http用、タイマー用、Webオーディオ用など、さまざまな処理を行うさまざまなリアクションライブラリを使用するのが自然です。それぞれが独自のケースに適した最適化/動作を実行できます。 ただし、1回限りの外部アクションを大量に実行するアプリがある場合は、あまり役に立たないようです。

記述に(状態スナップショットではなく)getStateを取得してディスパッチさせます。 そうすれば、必要に応じて非同期にすることができます。

私はしません。 私の見解では、非同期を可能な限り制限したいのであり、それを使用するための追加の方法を提供するのではありません。 getState()を呼び出したい場合は、レデューサー関数またはリアクション関数で実行する必要があります。 (しかし、それは私の純粋な考え方であり、おそらくそれに従わないという現実的なケースがあります。)

フェアポイント。 私はあなたのアイデアと@tauroseの例との間のマッピングについてはよく考えていません。 describereactions関数だと急いで思いましたが、そうではないかもしれません。

しかし、ええ、非同期を制限することが理想的であることに同意します。なぜなら、あなたのアイデアの推力を理解する場合、継続を純粋にし、状態の特定の側面と1:1でマッピングすることを望んでいるからです。たとえば、その意図を説明する配列メンバーの存在などです。与えられた効果が進行中です。 そうすれば、それらが複数回実行されるかどうかは実際には問題ではなく、他のプロセスが暗黙的に依存する可能性のあるフローの途中でプロセスが停止するという隠れた側面はありません。

記述に(状態スナップショットではなく)getStateを取得してディスパッチさせます。 そうすれば、必要に応じて非同期にすることができます。

describeは状態が変わるたびに呼び出されるので、その必要性はわかりません。 非同期ができないという意味ではありません。 反応コンポーネントを検討してください。現在の状態を取得するためにレンダリングメソッドまたはイベントハンドラー内でgetState呼び出すのではなく、小道具から読み取ります。

しかし、それ自体では非同期で何もできない(すべきではない)という点であなたは正しいです。 それをドライバーに任せて、マップされた状態やコールバックを渡すだけです。

想定される記述は反応関数でしたが、それは正しくない可能性があります。

私の知る限り、それはほとんど同じです。 1つの違いは、 reactionsdispatch取得しないことです。 したがって、 describeはアクションを作成してディスパッチするコールバックを返しますが、 reactionsはアクションの作成者を返します。

@winstonewert長いスレッドで、今読んだりコードをチェックしたりする時間がありませんが、 @ yelouafiが答えてくれるかもしれません。

redux-sagaプロジェクトは、ここでの長い議論から始まり

また、本番アプリで1年以上sagaの概念を使用しています。実装は表現力が劣りますが、ジェネレーターに基づいていません。 これが私がreduxの概念について与えたいくつかの疑似例です:

ここでの実装は完璧にはほど遠いですが、それはただのアイデアを与えるだけです。

@yelouafiは、reduxの外部で状態を非表示にするジェネレーターの使用に固有の問題を認識しており、バックエンドでサガを開始し、その非表示の状態をユニバーサルアプリのフロントエンドに送信するのは複雑です(本当に必要な場合)。

redux-sagaは、FreeがIOモナドに対してであるように、redux-thunkに対してです。 効果は宣言型であり、現在は実行されていません。イントロスペクトでき、インタープリターで実行できます(将来カスタマイズする可能性があります)。

ジェネレーター内の隠された状態についてのあなたのポイントを理解しています。 しかし、実際には、ReduxストアはReduxアプリのの正しい

レデューサーを使って佐賀のコンセプトを作成するImhoは、概念的には悪い考えではありません。私は、それがトレードオブの決定であることに同意します。
個人的には、サガを本番環境で1年以上使用した後、サガの状態をスナップショットして後で復元できると便利だったユースケースを覚えていないので、これを失ってもジェネレーターの表現力が好きです。特徴。

私が言っていることが、redux-sagaへの攻撃として出くわしたことを願っています。 私はそれが私が思いついたアプローチとどのように違うかについて話していました。

ジェネレーター内の隠された状態についてのあなたのポイントを理解しています。 しかし、実際には、ReduxストアはReduxアプリの真の正しい情報源ですか? そうは思いません。 Reduxはアクションを記録し、それらを再生します。 これらのアクションをいつでも再生して、ストアを再作成できます。 reduxストアは、イベントログのCQRSクエリビューのようなものです。 それは、そのイベントログの唯一の予測である必要があるという意味ではありません。 同じイベントログをさまざまなクエリビューに投影し、サガでそれらをリッスンできます。サガは、テクノロジーに関係なく、ジェネレーター、グローバルな可変オブジェクト、またはリデューサーを使用して状態を管理できます。

ここでのあなたの主張はよくわかりません。 佐賀はイベントログの投影であるとあなたは主張しているようですか? しかし、そうではありません。 アクションを再生すると、サガが非同期イベントに依存している場合、サガの同じ場所に到達できません。 sagasがreduxの状態ストアにもイベントログの予測にも存在しない状態を生成することは避けられないように思えます。

私の知る限り、それはほとんど同じです。 1つの違いは、リアクションがディスパッチされないことです。 したがって、describeはアクションを作成してディスパッチするコールバックを返しますが、reactionsはアクションの作成者を返します。

同意しました。 原則として、reactは同じインターフェースを使用でき、すべてのイベントハンドラーは、イベントが発生したときにディスパッチされるアクションクリエーターを実行します。

これについて考えれば考えるほど、このアプローチとサガの間には多くの相乗効果があると思います。 @winstonewertが概説した4つのポイントに完全に同意します。 リアクションがユーザーが開始したアクションを認識できないのは良いことだと思います。これにより、非表示の状態が防止され、レデューサーのビジネスロジックをアクションクリエーターやサガで複製する必要がなくなります。 ただし、副作用により、reactストア、間隔、domオブジェクト、httpリクエストなどに保存できないシリアル化できない状態が作成されることがよくあります。sagas、rxjs、baconjsなどは、この外部のシリアル化できない制御状態に最適です。

doReactionsはサガに置き換えることができ、サガのイベントソースはアクションではなくリアクションである必要があります。

私が言っていることがredux-sagaへの攻撃として出くわしたことを願っています

全くない。 私は議論をフォローしてきましたが、あなたのコードをもっと詳しく調べずにコメントしたくありませんでした。

一見。 状態の変化にしか反応しないようです。 私が言ったように、それは簡単な一見でした。 ただし、複雑なフローの実装は、elmアプローチ(状態とアクションの両方を実行する)よりもさらに難しくなるようです。 これは、さらに多くの制御状態をストアに保存する必要があることを意味します(アプリの状態の変化だけでは、関連する反応を推測するには不十分です)

確かに、純粋関数に勝るものはありません。 レデューサーは状態遷移を表現するのに最適だと思いますが、ステートマシンに変えると本当に奇妙になります。

これは、さらに多くの制御状態をストアに保存する必要があることを意味します(アプリの状態の変化だけでは、関連する反応を推測するには不十分です)

うん。 これは、このアプローチの重要な差別化の側面であるように私には思えます。 しかし、実際には、さまざまなエフェクトタイプをさまざまな「ドライバー」にまとめることができるので、この問題を透過的にすることができるのだろうか。 必要なドライバーを選択したり、斬新な効果を出すために独自のドライバーを作成したりするのは非常に簡単だと思います。

ただし、副作用により、reactストア、間隔、domオブジェクト、httpリクエストなどに保存できないシリアル化できない状態が作成されることがよくあります。sagas、rxjs、baconjsなどは、この外部のシリアル化できない制御状態に最適です。

私はあなたがまだ何であるかを見ていません。

レデューサーは状態遷移を表現するのに最適だと思いますが、ステートマシンに変えると本当に奇妙になります。

同意します。 複雑なステートマシンを手書きしている場合、問題が発生します。 (実際には、ジェネレーターをレデューサーに変換できれば便利です)。

しかし、実際には、さまざまなエフェクトタイプをさまざまな「ドライバー」にまとめることができるので、この問題を透過的にすることができるのだろうか。 必要なドライバーを選択したり、斬新な効果を出すために独自のドライバーを作成したりするのは非常に簡単だと思います。

ここで何を考えているのかわかりません。 さまざまなドライバーがさまざまな便利なことをしているのを見ることができますが、制御状態を排除していますか?

@winstonewertいいえ私は攻撃として何も取っていません。 私はあなたのコードを実際に見る時間さえありませんでした:)

ここでのあなたの主張はよくわかりません。 佐賀はイベントログの投影であるとあなたは主張しているようですか? しかし、そうではありません。 アクションを再生すると、サガが非同期イベントに依存している場合、サガの同じ場所に到達できません。 sagasがreduxの状態ストアにもイベントログの予測にも存在しない状態を生成することは避けられないように思えます。

いいえ、そうではありません。reduxストアはプロジェクションですが、サガは昔ながらのシンプルなリスナーです。

佐賀(プロセスマネージャーとも呼ばれる)は新しい概念ではなく、CQRSの世界に端を発し、過去にバックエンドシステムで広く使用されてきました。

佐賀は、イベントログをデータ構造に投影するのではなく、システムで起こっていることをリッスンして反応を発することができるオーケストレーションの一部であり、残りは実装の詳細です。 一般に、sagasはイベントログ(および時間などの他の外部のもの)をリッスンしており、新しいコマンド/イベントを生成する場合があります。 また、バックエンドシステムでイベントを再生する場合、通常、sagasによってトリガーされる無効化の副作用を無効にします。

違いは、バックエンドシステムでは、サガは実際にはイベントログの投影であることが多いということです。状態を変更するには、イベントを発行してそれ自体をリッスンする必要があります。 現在実装されているredux-sagaでは、イベントログを再生してsagaの状態を復元するのは困難です。

ここで何を考えているのかわかりません。 さまざまなドライバーがさまざまな便利なことをしているのを見ることができますが、制御状態を排除していますか?

いや、それを排除するのではなく、ほとんどの目的のために、それを内部的な実装の懸念にするだけです。

Reduxコミュニティには、ドメインの状態をストアに保存することが大きなメリットであるという強いコンセンサスがあるように思われます(そうでなければ、なぜReduxを使用するのでしょうか?)。 UIの状態をコンポーネントにカプセル化するのとは対照的に、UIの状態を保存することが有利であるというコンセンサスはやや少なくなります。 次に、URL(redux-simple-router)やフォームデータなど、ストア内のブラウザーの状態を同期するというアイデアがあります。 しかし、これは、長期にわたるプロセスのステータス/ステージをストアに保存するという最後のフロンティアのようです。

これが正接である場合は申し訳ありませんが、開発者の使い勝手が良い非常に一般的なアプローチには、次の機能が必要だと思います。

  • 一般的なユーザーがストアでの効果の表現方法の形を気にする必要がないようにします。 それらは、それらの詳細を抽象化する単純なAPIと対話する必要があります。
  • エフェクトを簡単に作成できるようにします。 制御フローや他の効果を条件とする効果などを行うのは自然なことです。 もちろん、これはジェネレータの抽象化が本当に輝いているところです。 ほとんどの制御フローでうまく機能しますが、クロージャは注目に値する例外です。 しかし、複雑な非同期フローがredux-sagaまたはreact-redux-controllerでどのように表現できるかは簡単にわかります。
  • 必要に応じて、効果のステータスを他の店舗の消費者に簡単に表示できるようにします。 これにより、マルチエフェクトプロセスのステータスをユーザーに提示するなどのことができます。
  • これは明らかかもしれませんが、状態をカプセル化するサブシステムは、アクションをディスパッチすることにより、その状態をReduxと同期します。

その2点目は、redux-sagaにかなり似たものが必要だと思います。 callラッパーで私が考えているものにかなり近づくかもしれません。 しかし、サガは、ある意味で「早送り可能」である必要があります。これにより、サガを中間状態に逆シリアル化できます。

これはすべて一種の難しい注文ですが、実際には、1つの中央のシリアル化可能なアクションレコードを持ち、アプリ全体の状態を非常に詳細なレベルで追跡することで大きな成果が得られるとしたら、これはそれを活用する方法。 そして、私は確かにそこに大きな勝利があるかもしれないと思います。 私は、ユーザー分析とパフォーマンス分析を使用してアプリを計測するためのはるかに簡単な方法を想像しています。 さまざまなサブシステムが状態を通じてのみ結合される、本当に驚くべきテスト容易性を想像しています。

私は今コースから外れたかもしれないので、そのままにしておきます:)

@acjay私たちはこれらの点であなたに同意すると思います、問題はそれらすべてを正しく解決するこの実装を見つけることです:)

しかし、ジェネレーターを使用した表現力豊かなAPIと、タイムトラベルおよびスナップショット/復元状態の可能性の両方を実現するのは難しいようです...ジェネレーターの状態を簡単に復元できるように、エフェクトの実行をメモ化できる可能性があります...

確かではありませんが、これはwhile(true) { ... }スタイルのサガを排除する可能性があります。 ループは、状態の進行の結果でしょうか?

@acjay @slorber

(https://github.com/yelouafi/redux-saga/issues/22#issuecomment-168872101)で説明したように、サガでは一人で(つまりホットリロードなし

実際のマスターブランチ(npmではまだリリースされていません)。 Sagasは監視をサポートし、生​​成されたすべての効果と、その結果をアクションとしてストアに送信します。 また、制御フローグラフをトレースするための階層情報も提供します。

そのエフェクトログを利用して、特定のポイントまで佐賀を再生できます。ログにはすでに過去の応答が含まれているため、実際のAPI呼び出しを行う必要はありません。

リポジトリの例には、sagaモニター(Reduxミドルウェアとして実装)の例があります。 エフェクトログをリッスンし、内部ツリー構造を維持します(十分に構築されています)。 アクション{type: 'LOG_EFFECT'}をストアにディスパッチすることで、フローのトレースを印刷できます。

これは、非同期の例からのエフェクトログのキャプチャです。

saga-log-async

編集:申し訳ありませんが固定画像のリンク

興味をそそる! そして、その開発ツールのイメージは_awesome_です。

カッコいい :)

確かに、その佐賀モニターはかなりクールです。

考えてみると、佐賀は2つの問題を解決しているように思えます。 まず、非同期効果を処理します。 第二に、それは、そうでなければレデューサーで不快な手書きのステートマシンを必要とするであろう複雑な状態の相互作用を処理します。

私のアプローチは最初の問題にのみ取り組んでいます。 2番目の問題の必要性は見つかりませんでした。 おそらく、私はまだそれに遭遇するのに十分なreduxコードを書いていません。

ええ、でも、2つのアイデアを融合させる方法があるのだろうか。 redux-sagaのcallラッパーは、エフェクトに対する非常に単純なレベルの間接参照ですが、さまざまなタイプのエフェクトのドライバーを使用してミドルウェアを初期化できると仮定すると、それらのエフェクトを、関数から切り離されたJSON可能なデータとして表すことができます。それは実際に呼ばれています。 ドライバーは、基になる状態の変化をストアにディスパッチする詳細を処理します。

これは、実用上のメリットがほとんどないため、非常に複雑になる可能性があります。 しかし、この考え方を最後までたどろうとしているだけです。

わかりました。ライブラリをさらにまとめて、実際の例を移植して使用しました。

まず、リアクションを実装します。
https://github.com/winstonewert/redux-reactions/blob/master/src/index.js
インターフェイスは3つの関数です。startReactionsはストア、リアクション関数、および名前からドライバーへのマッピングを取得します。 fromEmitterとfromPromiseFactoryはどちらもドライバーを作成します。

この例では、startReactionsを呼び出してシステムを有効にします。
https://github.com/winstonewert/redux-reactions/blob/master/examples/real-world/store/configureStore.dev.js#L28

反応の基本的な構成は次のとおりです。
https://github.com/winstonewert/redux-reactions/blob/master/examples/real-world/reactions/index.js。
反応関数は、実際には、reactions()関数を使用して、そのページに実際に必要な反応を把握するために、reactルーターがインスタンス化するコンポーネントを反復処理します。

github apiリアクションタイプの実装は次のとおりです: httpshttps

ここでコンポーネント固有の反応関数を参照してください: https

反応の作成者と共通のロジックはhttps://github.com/winstonewert/redux-reactions/blob/master/examples/real-world/reactions/data.jsにあります

みなさん、こんにちは! Raiseは、Elmアーキテクチャのようなエフェクトシステムも使用できるストアエンハンサーを公開しました。 コミュニティのすべてのニーズを満たすために、今後これらすべてのアプローチを学び、改善できることを願っています:smile:

https://github.com/raisemarketplace/redux-loop

ディスカッションに興味のある人は、ここで私のアイデアに関するさらなるディスカッションを見たいと思うかもしれません: https

ここでブランチを確認することもできます。ここでは、パターンを使用してカウンターアプリをより洗練されたものに作り直しています。
https://github.com/winstonewert/redux-reactions/tree/elmish/examples/counter

また、ここで使用されているアプローチを再発明していることも発見しました: https

ねえ@yelouafi 、佐賀モニターのアイデアへのリンクを再投稿してもらえますか? それは本当に素晴らしいものです! リンクが切れているようです(404)。 もっと見たいです!

関連する新しいディスカッション: https

(これは関連していると思います。間違った場所であれば申し訳ありません)

すべての効果をDOMレンダリングと同じように扱うことができるでしょうか。

  1. jQueryは、命令型インターフェイスを備えたDOMドライバーです。 Reactは、宣言型インターフェースを備えたDOMドライバーです。 したがって、「そのボタンを無効にする」という順序を付ける代わりに、「そのボタンを無効にする必要がある」と宣言すると、ドライバーがDOM操作を行うかどうかを決定します。 「 GET \product\123 」を注文する代わりに、「そのデータが必要」と宣言し、ドライバーが送信/キャンセルするリクエストを決定します。
  2. ReactコンポーネントをAPItoDOMドライバーとして使用します。 それらを使用して、他のドライバーとのインターフェースも行いましょう。

    • <button ...> -「通常の」ReactコンポーネントからViewレイヤーを構築します

    • <Map ...> -「ラッパー」コンポーネントを使用して、一部のライブラリの命令型インターフェイスを宣言型インターフェイスに変換します。 これらは「通常の」コンポーネントと同じように使用しますが、内部的には実際にはドライバーです。

    • <Chart ...> -これは、実装に応じて上記のいずれかになります。 したがって、「通常の」コンポーネントとドライバーの間の境界線はすでにぼやけています。

    • <Http url={'/product/'+props.selectedProductId} onSuccess={props.PRODUCT_LOADED} /> (または「スマート」 <Service...> )-サービスレイヤーを(UIなしの)ドライバーコンポーネントから構築します

ビューレイヤーとサービスレイヤーの両方がReactコンポーネントを介して記述されます。 そして、トップレベルの(接続された)コンポーネントがそれらを接着します。
このようにして、レデューサーは純粋なままであり、効果を処理するための新しい手段を導入しません。

new DateまたはMath.randomがここにどのように適合するかわかりません。

命令型APIを宣言型APIに変換することは常に可能ですか?
これは実行可能な見方だと思いますか?

ありがとう

非同期アクション用のsagaやその他の優れたツールがあることを考えると、これを安全に閉じることができると思います。 いくつかの興味深い新しい方向性については、#1528をチェックしてください(非同期だけでなく)。

このページは役に立ちましたか?
0 / 5 - 0 評価