Redux-SagaではなくRedux-Observableを使用する理由


133

私はRedux-Sagaを使用しました。それを使って書かれたコードは、JSジェネレーター関数が時々混乱していることを除いて、これまでのところ簡単に推論できます。私の理解から、Redux-Observableは、ジェネレーター関数を使用せずに、副作用を処理する同様のジョブを実行できます。

ただし、Redux-Observableのドキュメントには、Redux-Sagaより優れている理由についての多くの意見はありません。ジェネレータ関数を使用しないことがRedux-Observableを使用する唯一の利点であるかどうかを知りたいのですが。そして、Redux-Sagaの代わりにRedux-Observableを使用することの欠点、落とし穴、または妥協点は何ですか?前もって感謝します。


私は楽しく、しかし詳細なブログを書いていて、一日中生きている/食べている/呼吸していない人々にとって、Redux-SagaがRedux-Observableより優れていることを発見しました。あなたのスタック全体がオブザーバブルであるならば、それは素晴らしいことだと私は確信しています。 shift.infinite.red/…–
Gant Laborde

回答:


236

免責事項:私はredux-observableの作成者の1人なので、100%公平であるのは難しいです。

現時点では、redux-observableがredux-sagaよりも優れている理由を提供していません。なぜなら、そうではないからです。😆

tl; dr両方の長所と短所があります。多くの人は一方が他方よりも直感的であると感じますが、RxJS(redux-observable)またはgenerators / "effects as data"(redux-saga)がわからない場合、両方を異なる方法で学習するのは複雑です。

それらは非常に類似した方法で同じ問題を解決しますが、十分に使用したときに初めて明らかになるいくつかの根本的な違いがあります。

redux-observableは、ほとんどすべてを慣用的なRxJSに委ねます。したがって、RxJSの知識がある(またはそれを得る)場合、redux-observableの学習と使用は非常に自然なことです。これはまた、この知識がredux以外のものに転送可能であることを意味します。MobXへの切り替えを決定した場合、Angular2への切り替えを決定した場合、将来のホットネスXへの切り替えを決定した場合、RxJSが役立つ可能性が非常に高くなります。これは、RxJSが一般的な非同期ライブラリであり、多くの点でプログラミング言語自体、つまり「リアクティブプログラミング」パラダイム全体に似ているためです。RxJSは2012年から存在し、Rx.NETのポートとして開始されました(ほぼすべての主要言語に「ポート」があり、非常に便利です)。

redux-sagaは時間ベースのオペレーター自体を提供するため、このプロセスマネージャースタイルでのジェネレーターと副作用の処理について習得した知識は伝達可能ですが、実際のオペレーターと使用法は他の主要なライブラリでは使用されません。ですから、それは少し残念なことですが、それだけで取引のブレーカーになるべきではありません。

また、「データとしての効果」(ここで説明)を使用しますが、最初は頭を一周するのは難しいかもしれませんが、redux-sagaコードは実際には副作用自体を実行しません。代わりに、使用するヘルパー関数は、副作用を実行する意図を表すタスクのようなオブジェクトを作成し、内部ライブラリがそれを実行します。これにより、モックする必要がなく、テストが非常に簡単になり、一部の人々にとって非常に魅力的です。ただし、個人的には、ユニットテストがサガのロジックの多くを再実装することを意味します-これらのテストをあまり役に立たないIMOにします(この意見は全員に共有されるわけではありません)

人々はよく、なぜredux-observableでそのようなことをしないのかと尋ねます:私にとって、それは通常の慣用的なRxと根本的に互換性がありません。Rxでは、.debounceTime()デバウンスに必要なロジックをカプセル化するような演算子を使用しますが、実際にはデバウンスを実行せず、代わりにインテントでタスクオブジェクトを放出するバージョンを作成したい場合は、操作の実際の結果ではなく、オペレーターがそのタスクオブジェクトを操作しているため、オペレーターをチェーンすることができないため、Rxのパワー。これを上品に説明するのは本当に難しいです。アプローチの非互換性を理解するには、Rxを深く理解する必要があります。あなたが本当にそのようなものを望んでいるなら、redux-cyclesをチェックしてくださいこれはcycle.jsを使用し、主にそれらの目標を持っています。私の好みにはあまりにも多くの儀式が必要だと思いますが、興味があれば試してみることをお勧めします。

ThorbenAが述べたように、私はredux-sagaが現在(10/13/16)reduxの複雑な副作用管理の明確なリーダーであることを認めることをためらいません。それは以前に開始され、より堅牢なコミュニティがあります。したがって、ブロックの新しい子供よりも事実上の標準を使用することに多くの魅力があります。どちらかを事前の知識なしに使用すると、混乱を招くと言っても安全だと思います。どちらもかなり高度な概念を使用しており、一度「取得」すると、複雑な副作用の管理がはるかに容易になりますが、それまでは多くの問題がありました。

私が与えることができる最も重要なアドバイスは、必要になる前にこれらのライブラリのどちらも持ち込まないことです。単純なajax呼び出しのみを行う場合は、おそらく必要ありません。redux-thunkは学習するのが簡単で愚かであり、基本を十分に提供しますが、非同期が複雑になるほど、redux-thunkはより難しくなります(または不可能にさえなる)。しかし、多くの点でredux-observable / sagaにとって、非同期がより複雑であるほど、それは最も輝きます。同じプロジェクトでredux-thunkを他の1つ(redux-observable / saga)と一緒に使用することには多くのメリットもあります!一般的な単純なものにはredux-thunkを使用し、複雑なものにはredux-observable / sagaのみを使用します。これは生産性を維持するための優れた方法であるため、redux-thunkで取るに足らないことについてredux-observable / sagaと戦うことはありません。


3
ちょうどあなたの話を(うーん音!)、すぐに⌘+ T +「redux-saga vs redux-observable」を押します。私はかなり長い間(特にReact Nativeで)redux-sagaを使用してきましたが、あなたの話とこの投稿を見た後、redux-obsの(私にとっての)いくつかのユースケースを見ることができます。実際にはより良い適合です。debounceTime()非常に一般的なロジックに対する制御を「失った」あなたの例は、私にとってそれをヒットさせました。説明していただきありがとうございます。
Hulvej

3
ちょうど話も見て、もう少しグーグルでやった。共有してくれてありがとう@jayphelps 特に、redux-observable / sagaと組み合わせてredux-thunkを使用することについてのコメントが好きです。これは非常に理にかなっています。単純なAJAXリクエストが不必要なときに複雑すぎる理由です。とはいえ、統一性と人々の一貫性を保つために言うべきことがあります。再度、感謝します!
スペッツ2017

redux-saga / redux-observableにアップグレードする前に、redux-dispatch-listenerを試すことができます。これは非常に簡単で、すでにいくつかのユースケースを解決できます。github.com/ slorber
Sebastien Lorber

これは非常に役立つ回答でした。ありがとうございました!RxJSの知識を他のドメイン/フレームワークに転送できる点が気に入っています。
Anselan

@jayphelps「複雑な非同期」の例は何でしょうか。現在、プロジェクトのサンクからサーガ/オブザーバブルに切り替える必要があるかどうかを評価しています。ありがとう:)
Sam Bokai

64

考慮しなければならないことがあると思います。

  1. 複雑
  2. コーディングスタイル
  3. 学習曲線
  4. テスト容易性

APIからユーザーをフェッチしたいとしましょう

// Redux-Saga

import axios from 'axios' 

function* watchSaga(){
  yield takeEvery('fetch_user', fetchUser) // waiting for action (fetch_user)
}

function* fetchUser(action){
    try {
        yield put({type:'fetch_user_ing'})
        const response = yield call(axios.get,'/api/users/1')
        yield put({type:'fetch_user_done',user:response.data})
  } catch (error) {
        yield put({type:'fetch_user_error',error})
  }
}

// Redux-Observable
import axios from 'axios'

const fetchUserEpic = action$ => 
    action$
        .ofType('fetch_user')
        .flatMap(()=>
          Observable.from(axios.get('/api/users/1')) // or use Observable.ajax
            .map(response=>({type:'fetch_user_done', user:response.data}))
            .catch(error => Observable.of({type:'fetch_user_error',error}))
            .startWith({type:'fetch_user_ing'})
        )

また、この記事は、Redux-sagaとRedux-Observableの違いを詳細に比較するために作成しました。こちらのリンクまたはプレゼンテーションをご覧ください。


3
リンクからのこの並べて比較は素晴らしいです、ありがとう
rofrol

1
私は比較が好きですが、育てたい問題があります。API呼び出しを使用してそれらを比較する場合-redux-observableのフェッチを使用しています。涼しい。しかし、「キャンセル可能な」違いを表示する場合、フェッチを使用せず、代わりに内部のObservable.ajaxを使用します...なぜですか?「フェッチ」または「アキシオス」を使用してそれを維持したいと思います。そうでなければ、素晴らしい仕事です。
james emanon 2017

5
@jamesemanonフェッチAPIにはまだキャンセルするオプションがないため、彼はフェッチを使用していないと思います。(これについての詳細:github.com/whatwg/fetch/issues/27
Daniel Andrei

うわー、すべての例との徹底的な比較は最高です。ありがとうございました!
RadekMatěj19年

22

ジェネレーターではなくオブザーバブルを使用することを好むので、Redux-SagaではなくRedux-Observableを使用します。データのストリームを操作するための強力なライブラリーであるRXJSで使用します。非同期のlodashのように考えてください。欠点、落とし穴、およびどちらか一方を選択する際の妥協点については、Jay Phelpsの次の回答をご覧ください。

プロジェクトとしてのredux-sagaはredux-observableよりも長く存在していたので、それは確かに1つの主要なセールスポイントです。あなたはより多くのドキュメント、例を見つけるでしょう、そしておそらくサポートを得るためのより良いコミュニティを持っているでしょう。

カウンターは、redux-sagaで学ぶオペレーターとAPIは、RxJSを学ぶのと同じぐらい転送可能ではないということです。これは、至る所で使用されています。redux-observableは、内部的には非常に単純で、RxJSを使用するための自然な方法を提供しているだけです。したがって、RxJSを知っている(またはしたい)場合、それは非常に自然な適合です。

現在のところ、ほとんどの人に対する私のアドバイスは、どちらを使用するかを尋ねる必要がある場合は、おそらくredux-sagaを選択する必要があるということです。


9

Redux-Observableは素晴らしいライブラリであり、1.5年間本番環境で問題なく使用しています。完全にテスト可能で、任意のフレームワークと簡単に統合できます。非常に過負荷の並列ソケットチャネルがあり、フリーズから私たちを救っている唯一のものはRedux-Observableです

ここで3点申し上げたいと思います。

1.複雑さと学習曲線

Redux-sagaはここでredux-observableを簡単に打ち負かします。承認を取得するための単純なリクエストだけが必要で、何らかの理由でredux-thunkを使用したくない場合は、redux-sagaの使用を検討する必要があります。

Observableの事前知識がない場合、それはあなたにとって苦痛であり、あなたのチームはあなたを訓練します:)

2. ObservableとRxJSは何を提供できますか?

非同期ロジックに関して言えば、Observableはあなたのスイスのナイフです。Observableは文字通りほとんどすべてを行うことができます。それをはるかに強力なプロミスやジェネレーターと決して比較しないでください。これはOptimus PrimeとChevroletを比較するのと同じです。

そしてRxJSはどうですか?それはlodash.jsに似ていますが、非同期ロジックの場合、いったん別の場所に切り替えることはありません。

3.リアクティブ拡張

このリンクをチェックしてください

http://reactivex.io/languages.html

リアクティブ拡張機能は、すべての最新のプログラミング言語に実装されています。これは、関数型プログラミングの鍵にすぎません。

したがって、RxJSを賢く学び、redux-observableを使用して時間をかけてください:)


7

Rxが持つ言語とランタイム全体の転送可能性を評価します。アプリが言語を変更しなくても、キャリアは変わる可能性があります。学習で最大限のレバレッジを獲得しますが、自分のためにそれを大きくします。これは特に.Net LINQへの素晴らしいゲートウェイです。


2
ジェネレーターも言語に依存しませんが、賢い選択です。
Greg Herbowicz

3

ここには、reduxで観察可能な話がたくさんあるので、私は議論の佐賀側を与えると思いました。redux-observableやRxJSを使用していないため、並べて比較することはできませんが、sagasを使用して効果を上げています。

その価値のために、私はWebアプリケーションのプロダクションでsagasを使用しています。

サンガ対サンク

佐賀は勝つ。私はアクションクリエーターにサンクがどのようにロジックを入れるのが好きではありませんでした。また、いくつかのリクエストを続けて行うのは面倒です。私はこの仕事のredux-observableを簡単に調べましたが、Sagasに落ち着きました。

サガの学習曲線

ジェネレーターとは何か、なぜジェネレーターが重要なのかを理解することは、サーガを理解するための鍵です。しかし、私はあなたジェネレーターの内外を知る必要がないことを強調します。必要なのは、yieldステートメントを使用して制御を渡すことと、非同期コードが解決された後に佐賀が制御を戻すことだけです。その後、佐賀で何が起こっているのかを理解するのはそれほど難しくありません。

コアサガメソッドは(私の経験では):

  • call-任意のコードを呼び出して戻り値を取得します。約束をサポートします。非同期処理とサガの間の大きな相乗効果。
  • select-セレクターを呼び出します。このビットはかなり素晴らしいです。セレクターはreduxの中核であり、100%サポートされています!
  • put -別名 dispatchアクション。実は好きなだけ発送してね!

他にも機能はありますが、これら3つをマスターできれば、本当にいい場所になります。

結論

サガを選んだ理由は、使いやすさです。redux-observableは課題のように見えました。私はサガに100%満足しています。想像以上に幸せ。

私の経験では、Sagasはサンクよりも(方法が)優れており、比較的理解しやすいです。Rxはみんなのお茶ではありません。あなたがそのエコシステムから来ていない、および/または将来Rxを使用する予定がない場合は、redux-observableの代わりにsagasを強く検討します。


2

Typescriptでアプリケーションを作成する場合は、typelessをチェックすることをお勧めしますます。これはRedux-Observableに触発されており、RxJSにも依存していますが、アプリを構築するためのエコシステム全体があります。

redux-observable / redux-sagaの最大の短所は、ガイドラインの欠如です。レデューサー、サガまたはエピックを遅延ロードする方法に関する公式のガイドラインはありません。より大きなアプリをスケーリングする場合、コード分割は重要です。遅延読み込みのカスタムソリューションは通常、HMRでは機能せず、開発者のエクスペリエンスが低下します。

タイプレスプロ:

  1. TypeScript用に設計
    すべてのAPIは、typescriptとタイプセーフのために設計されています。
    • Typescriptは生産性を向上させますが、遅くすることはありません。
    • 必要な注釈のみが必要です:状態、アクション引数。
    • タイプキャストなし。すべてが自動的に推測されます。コードの95%は純粋なJavaScriptのように見えます。
    • RootAction、RootEpic、RootState、またはその他のヘルパータイプはありません。
  2. すべてのビルディングブロックを提供する
    • Typelessには、中規模またはエンタープライズレベルのアプリを構築するためのすべてが含まれています。
    • 複数の小さなライブラリに依存する必要はありません。
  3. モジュール性
    • スケーラブルなアプリを構築するには、適切なモジュール性が重要です。
    • エピック、レデューサー、タイプなどのルートファイルを作成する必要はありません。新しいモジュールを作成したら、どこからでも接続できます。標準のReactコンポーネントに似ています。
  4. 意見
    • すべての一般的な使用例と問題はデフォルトで解決されます。些細な問題を修正する方法を考え直す必要はありません。
    • すべての推奨事項とベストプラクティスが提供されます!

https://typeless.js.org/をチェックしてください。


1
主な貢献者であるソフトウェアを推奨する場合は、免責事項を追加する必要があります。
Hagelt18
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.