Facebook FluxでReduxを使用する理由 [閉まっている]


1126

私はこの答えを読んで、ボイラープレートを減らし、GitHubの例をいくつか見て、少しやり直してみました(todoアプリ)。

私が理解しているように、公式のredux doc動機は、従来のMVCアーキテクチャと比較して長所を提供します。しかし、それは質問に対する答えを提供しません:

Facebook FluxではなくReduxを使用する理由

それはプログラミングスタイルの問題だけですか?機能か非機能か?または、問題はreduxアプローチから続く能力/開発ツールにありますか?たぶんスケーリング?またはテスト?

reduxは関数型言語から来た人々にとって流動的なものだと言ってもよろしいですか?

この質問に答えるために、実装の複雑さを比較することができます。

公式のredux docモチベーションのモチベーションポイントは次のとおりです。

  1. 楽観的な更新の処理(私が理解しているように、5番目の点にほとんど依存しません。Facebookの変化に実装するのは難しいですか?
  2. サーバーでのレンダリング(facebookフラックスでもこれを行うことができます。reduxと比較して何か利点はありますか?
  3. ルート遷移を実行する前にデータを取得する(facebookフラックスではなぜそれができないのですか?利点は何ですか?
  4. ホットリロード(React Hot Reloadで可能です。なぜreduxが必要なのですか?
  5. 元に戻す/やり直し機能
  6. その他のポイントは?持続する状態のように...

73
Reduxは「Facebook Flux」の実装です。Fluxはライブラリやフレームワークではありません。これは、単にWebアプリケーションに推奨されるアーキテクチャです。具体的な実装を、その動機となった抽象的な概念とどのように比較できるかわかりません。FacebookのFluxアーキテクチャの実際の実装はRelayであり、オープンソースバージョンはまだ非常に初期の段階です。facebook.github.io/relay
チャーリーマーティン

2
@CharlieMartin By FB Fluxこのアプリケーションをgithub.com/facebook/flux/tree/master/examplesのように記述します。私の現在のプロジェクトはFB Flux(予定はFB Flux)で書かれています。必要に応じて、FB FluxアーキテクチャーよりもReduxアーキテクチャーと考えることができます。
VB_ 2015

2
今、私は分かる。FacebookのFlux実装の例とReduxのFlux実装を比較したい
チャーリーマーティン

13
リレーはFluxの実装ではありません-リレー/ GraphQLはサーバーでのデータのフェッチ/クエリの管理に重点を置いていますが、フラックスは主にクライアント側のデータモデルとビューコンポーネント間のデータフローの構造に関係しています。ただし、一部重複があります。Facebookでは、Fluxを完全に使用して、Relayを完全に使用して、またはその両方でアプリを構築しています。浮上しているパターンの1つは、Relayがアプリケーションのデータフローの大部分を管理できるようにすることですが、アプリケーションの状態のサブセットを処理するためにサイドでFluxストアを使用します
Hal

回答:


1958

Reduxの作者はこちら!

Reduxのではありませんそのフラックスは異なります。全体的には同じアーキテクチャですが、Reduxは、Fluxがコールバック登録を使用する関数構成を使用することで、複雑さの一部を削減できます。

Reduxには基本的な違いはありませんが、Fluxで実装するのが難しい、または不可能である特定の抽象化を容易にするか、少なくとも実装することが可能になると思います。

レジューサー組成

たとえば、ページネーションを見てください。私のFlux + React Routerの例はページネーションを処理しますが、そのコードはひどいです。ひどい理由の1つは、Fluxが複数のストアで機能を再利用することを不自然にしていることです。2つのストアが異なるアクションに応じてページ分割を処理する必要がある場合は、共通のベースストアから継承する必要があります(悪い!継承を使用すると、特定のデザインにロックされます)、または内から外部定義関数を呼び出すFluxストアのプライベート状態で何らかの方法で動作する必要があるイベントハンドラー。全体が散らかっています(確かに可能の領域ではありますが)。

一方、Reduxでは、リデューサーの構成により、ページネーションは自然に行われます。それの減速あなたが書くことができるようにすべての方法ダウン、ページネーションの減速を発生させる減速機工場をして、自分の減速ツリーにそれを使用しますFluxではストアはフラットですが、Reduxでは、Reactコンポーネントをネストできるのと同じように、レデューサーを関数構成を介してネストできるためこれが非常に簡単な理由の鍵です。

このパターンは、非ユーザーコードの取り消し/やり直しなどの素晴らしい機能も有効にします。Undo / Redoを2行のコードであるFluxアプリに接続することを想像できますか?ほとんどありません。Reduxを使用すると、レデューサーコンポジションパターンのおかげで、これは再びです。何も新しいことはないことを強調する必要があります。これは、Fluxの影響を受けたElm Architectureで先駆的に説明されたパターンです。

サーバーレンダリング

人々はFluxを使用してサーバーで問題なくレンダリングしてきましたが、サーバーのレンダリングをより簡単にしようとする20のFluxライブラリがあることがわかりました。真実はFacebookがサーバーレンダリングをあまり行わないため、彼らはそれについてあまり気にしておらず、エコシステムに依存して簡単にしているのです。

従来のFluxでは、ストアはシングルトンです。これは、サーバー上の異なるリクエストのデータを分離するのが難しいことを意味します。不可能ではないが難しい。これが、ほとんどのFluxライブラリー(および新しいFlux Utils)がシングルトンの代わりにクラスを使用することを提案する理由です。これにより、リクエストごとにストアをインスタンス化できます。

Fluxで解決する必要がある次の問題がまだあります(自分で、またはFlummoxAltなどのお気に入りのFluxライブラリを使用して)。

  • ストアがクラスの場合、リクエストごとにディスパッチャーを使用してストアを作成および破棄するにはどうすればよいですか?店舗はいつ登録しますか?
  • ストアからのデータをハイドレートし、後でクライアントで再ハイドレートするにはどうすればよいですか?これには特別なメソッドを実装する必要がありますか?

確かにFluxフレームワーク(バニラFluxではない)はこれらの問題の解決策を持っていますが、私はそれらが過度に複雑であることを発見しました。たとえば、Flummoxは、実装serialize()およびdeserialize()店舗での実装を要求します。Alt takeSnapshot()は、JSONツリーで状態を自動的にシリアル化することで、この優れた解決策を提供します。

Reduxはさらに進んでいます:ストアが1つしかないため(多くのレデューサーによって管理されます)、(再)水分補給を管理するために特別なAPIは必要ありません。ストアを「フラッシュ」または「ハイドレート」する必要はありません。単一のストアがあり、現在の状態を読み取ったり、新しい状態で新しいストアを作成したりできます。各リクエストは個別のストアインスタンスを取得します。Reduxによるサーバーレンダリングの詳細をご覧ください。

繰り返しますが、これはFluxとReduxの両方で可能なことですが、Fluxライブラリは大量のAPIと規約を導入することでこの問題を解決します。Reduxは問題を解決しないため、第一に、概念の単純さのおかげです。

開発者の経験

Reduxを人気のあるFluxライブラリにするつもりはありませんでした。私は、ReactEuropeでタイムトラベルを伴うホットリロードに関する講演に取り組んでいたときに書いたのです。主な目的は1つでした。リデューサーコードをその場で変更したり、アクションに取り消し線を引いて「過去を変更」したり、状態が再計算されたりすることを確認することです。

これを行うことができる単一のFluxライブラリを見たことがありません。React Hot Loaderでもこれを行うことはできません。実際、Fluxストアを編集すると、何を行うかわからないため、Fluxストアが壊れます。

Reduxがレデューサーコードをリロードする必要がある場合、を呼び出しreplaceReducer()、アプリは新しいコードで実行されます。Fluxでは、データと関数がFluxストアで絡み合っているため、「関数を置き換えるだけ」ことはできません。さらに、なんとかして新しいバージョンをDispatcherに再登録する必要があります— Reduxにはないものです。

生態系

Reduxには、豊かで急速に成長しているエコシステムがあります。これは、ミドルウェアなどのいくつかの拡張ポイントを提供するためです。これは、ロギングPromisesObservablesルーティング不変性の開発チェック永続性などのサポートケースを念頭に置いて設計されました。これらのすべてが役立つとは限りませんが、簡単に組み合わせて連携できるツールのセットにアクセスできると便利です。

シンプルさ

Reduxは、Dispatcherとストア登録を導入することなく、Fluxのすべての利点(アクションの記録と再生、単方向のデータフロー、依存する変更)を維持し、新しい利点(簡単な元に戻す、やり直し、ホットリロード)を追加します。

より高いレベルの抽象化を実装する間、それを正気に保つので、それをシンプルに保つことは重要です。

ほとんどのFluxライブラリとは異なり、Redux APIサーフェスは小さいです。開発者の警告、コメント、健全性チェックを削除すると、99行になります。デバッグするトリッキーな非同期コードはありません。

実際にそれを読んで、Reduxのすべてを理解することができます。


Fluxと比較したReduxの欠点についての私の回答も参照してください。


3
答えてくれてありがとう...私はjsに慣れていません。あなたの答えでは、フラックスはシングルトン設計パターンを使用していると言いました...彼らが使用している設計パターンの種類をreduxで教えてください...そしてフラックスでシングルトンパターンを使用している場所を教えてください...両方の例を挙げていただけますか...私は、ここからシングルトンの

2
私はFluxxor(基本的には純粋なフラックス)に基づいてAndroid / Java実装(Fluxxan)を開始しました。reduxを見たら、売りに出された。私が純粋にフラックスを保ったいくつかの部分がありますが、あなたのlibは素晴らしいです!
霜降りの素晴らしい

5
あなたはReduxを学びたいですか?この
動画をご覧ください

5
私たちは、フラックスよりもずっと説得力があるということでreduxを選択しました。私たちは常に特定のコードがどこに/どこに行くべきかなどについて争っていました。Reduxはその混乱をすべて取り除いてくれました。私たちはウェブと反応ネイティブのためのreduxを使ってアプリを構築しました、そしてそれは素晴らしいです!!
SomethingOn

1
github.com/reactjs/redux/blob/…という行は、私が1週間探していた質問に対する答えでした。ストアとリデューサーを構造化して、異なるコンテキストで使用される再利用可能なコンポーネントの複数のインスタンスを複製せずに処理できるようにする方法論理。答えは次のようです:1レベル:コンポーネントの名前(「ページ付け」)、2レベル:コンテナーの名前(「stargazersByRepo」)、3レベル:コンテナーの一意のキー/ ID(3レベルのディープストアを使用)${login}/${name})。どうもありがとうございました!
qbolec 2017

101

Quoraでは、誰かが言う

まず第一に、FluxなしでReactでアプリを書くことは完全に可能です。

また、両方をすばやく表示するために作成したこのビジュアルダイアグラムは、説明全体を読みたくない人のための簡単な答えです。 Flux vs Redux

しかし、あなたがまだもっと知りたいと思っているなら、読み続けてください。

純粋なReactから始めて、ReduxとFluxを学ぶべきだと思います。Reactで実際の経験を積んだ後、Reduxが役立つかどうかを確認します。

たぶん、あなたはReduxがあなたのアプリにぴったりであると感じるかもしれませんし、多分あなたはReduxがあなたが実際に経験していない問題を解決しようとしていることに気付くでしょう。

Reduxを直接使用すると、コードが過度に設計され、コードの保守が難しくなり、Reduxを使用しない場合よりもさらに多くのバグが発生する可能性があります。

Redux docsから:

動機
JavaScriptの単一ページアプリケーションの要件がますます複雑になるにつれて、コードでこれまで以上に多くの状態を管理する必要があります。この状態には、サーバーの応答とキャッシュされたデータ、およびサーバーにまだ永続化されていないローカルで作成されたデータが含まれる場合があります。アクティブなルート、選択されたタブ、スピナー、ページネーションコントロールなどを管理する必要があるため、UI状態も複雑さを増しています。

この絶え間なく変化する状態を管理することは困難です。モデルが別のモデルを更新できる場合、ビューはモデルを更新でき、それが別のモデルを更新します。これにより、別のビューが更新される可能性があります。ある時点で、いつ、なぜ、どのように状態を制御できなくなったため、アプリで何が発生するか理解できなくなります。システムが不透明で確定的でない場合、バグを再現したり、新しい機能を追加したりすることは困難です。

これで十分ではなかったかのように、新しい要件がフロントエンド製品開発で一般的になることを考慮してください。開発者は、楽観的な更新、サーバー側のレンダリング、ルート遷移を実行する前のデータのフェッチなどを処理することが期待されています。これまでに対処する必要がなかった複雑さを管理しようとしていることに気づき、必然的に次の質問をします。答えはノーだ。

この複雑さは、人間の心が考えるのが非常に難しい2つの概念、つまり変異と非同期性を混合しているため、処理するのが困難です。私はそれらをメントスとコーラと呼んでいます。両方を分離すると素晴らしい場合がありますが、一緒にすると混乱を引き起こします。Reactのようなライブラリは、非同期と直接DOM操作の両方を削除することで、ビューレイヤーでこの問題を解決しようとします。ただし、データの状態の管理はユーザーに任されています。これがReduxの出番です。

Reduxは、Flux、CQRS、およびイベントソーシングの足跡をたどって、更新を行う方法とタイミングに特定の制限を課すことで、状態の変化を予測可能にしようとします。これらの制限は、Reduxの3つの原則に反映されています。

また、Redux docsから:

コアコンセプト
Redux自体は非常に単純です。

アプリの状態がプレーンオブジェクトとして記述されているとしましょう。たとえば、Todoアプリの状態は次のようになります。

{
  todos: [{
    text: 'Eat food',
    completed: true
  }, {
    text: 'Exercise',
    completed: false
  }],
  visibilityFilter: 'SHOW_COMPLETED'
}

このオブジェクトは、セッターがないことを除いて「モデル」に似ています。これは、コードのさまざまな部分が状態を勝手に変更できず、再現が難しいバグを引き起こすためです。

状態を変更するには、アクションをディスパッチする必要があります。アクションは、何が起こったかを説明するプレーンなJavaScriptオブジェクトです(どのように魔法を導入しないのですか?)。アクションの例をいくつか示します。

{ type: 'ADD_TODO', text: 'Go to swimming pool' }
{ type: 'TOGGLE_TODO', index: 1 }
{ type: 'SET_VISIBILITY_FILTER', filter: 'SHOW_ALL' }

すべての変更がアクションとして記述されることを強制することで、アプリで何が起こっているのかを明確に理解することができます。何かが変わった場合、その理由がわかります。アクションは、起こったことのパンくずのようなものです。最後に、状態とアクションを結び付けるために、レデューサーと呼ばれる関数を記述します。繰り返しになりますが、魔法はありません。状態とアクションを引数として取り、アプリの次の状態を返す関数です。大きなアプリに対してそのような関数を書くのは難しいので、状態の一部を管理する小さな関数を書きます。

function visibilityFilter(state = 'SHOW_ALL', action) {
  if (action.type === 'SET_VISIBILITY_FILTER') {
    return action.filter;
  } else {
    return state;
  }
}

function todos(state = [], action) {
  switch (action.type) {
  case 'ADD_TODO':
    return state.concat([{ text: action.text, completed: false }]);
  case 'TOGGLE_TODO':
    return state.map((todo, index) =>
      action.index === index ?
        { text: todo.text, completed: !todo.completed } :
        todo
   )
  default:
    return state;
  }
}

そして、対応する状態キーに対してこれら2つのレデューサーを呼び出すことにより、アプリの完全な状態を管理する別のレデューサーを記述します。

function todoApp(state = {}, action) {
  return {
    todos: todos(state.todos, action),
    visibilityFilter: visibilityFilter(state.visibilityFilter, action)
  };
}

これは基本的にReduxの全体的な考え方です。Redux APIを使用していないことに注意してください。このパターンを容易にするいくつかのユーティリティが付属していますが、主なアイデアは、アクションオブジェクトに応答して状態が時間とともに更新される方法を説明することであり、作成するコードの90%は単なるJavaScriptであり、Reduxを使用しませんそれ自体、そのAPI、または魔法。


57

Dan Abramovによるこの投稿を読んで、Fluxのさまざまな実装と、彼がredux:The Evolution of Flux Frameworksを書いていたときのトレードオフについて議論するのがよいでしょう。

第二に、あなたがリンクするその動機ページは、実際にはReduxの動機についてはFlux(およびReact)の背後にある動機ほどは議論していません。三原則は、まだ標準フラックスアーキテクチャから実装の違いに対処しませんが、よりReduxの固有のものです。

基本的に、Fluxには複数のストアがあり、UI / APIのコンポーネントとの対話に応じて状態変化を計算し、コンポーネントがサブスクライブできるイベントとしてこれらの変更をブロードキャストします。Reduxでは、すべてのコンポーネントがサブスクライブするストアは1つだけです。IMOは、少なくともReduxがコンポーネントへのデータフローを統合(またはReduxが言うように削減)することによってデータフローをさらに簡素化および統合するように感じます-一方、Fluxはデータフローの反対側の統合に集中しています-ビューモデル。


27

私はアーリーアダプターであり、Facebook Fluxライブラリを使用して中規模の単一ページアプリケーションを実装しました。

私が会話に少し遅れるとき、私は私の最高の希望にもかかわらずFacebookがFlux実装を概念の証明であると考えているようであり、それに値する注意を受けたことがないことを指摘しておきます。

非常に教育的なFluxアーキテクチャの内部動作の多くを公開しているので、それを試してみることをお勧めしますが、同時に、Reduxのようなライブラリが提供する多くの利点を提供しません(これらはありません)これは小さなプロジェクトでは重要ですが、大きなプロジェクトでは非常に価値があります)。

今後はReduxに移行することを決定しました。同じことをお勧めします;)


Facebook Fluxアプリを6か月間開発しています。そして、移行時間がReduxが提供する利点に値するかどうかはまだわかりません。FBフラックスに対するReduxの長所/短所に関するすべてのコメントに感謝します!
VB_16年

1
@VolodymyrBakhmatiuk私たちにとっては、ほとんどの場合、作成する必要のあるボイラープレートの量を削減すること+エラー処理を改善すること(たとえば、定数リストで定義されていないアクションを実行すると、reduxは怒鳴る-FBフラックスは発生せず、すべての原因となる可能性がある一種の問題)フラックスにはいくつかの高度な機能がありますが、まだ使用していません
Guy Nesher

1
@GuyNesher未定義のアクションは、実行時ではなくコンパイル時に検出されます。Flow(別のFacebookコントリビューション)では、それを行うことができます。
ドミニクペレッティ16

@DominiquePERETTI-true(lintingを使用することもできます)でも、実行時にエラーをキャッチしないのが少し悲しいという事実は変わりません
Guy Nesher

私はFBFluxを処理するためのいくつかの単純なヘルパーを書きましたが、実際には、私が見つけたすべてのReduxアプリの例よりも定型文やアプリの設定が少ないようです。2人の開発者の間で9か月以上もアプリを開発し、アーキテクチャにまったく問題がありませんでした。
rob2d 2017年

20

ここでは、Fluxに対するReduxの簡単な説明を示します。Reduxにはディスパッチャーがありません。レデューサーと呼ばれる純粋な関数に依存しています。ディスパッチャーは必要ありません。各アクションは、単一のストアを更新するために1つ以上のレデューサーによって処理されます。データは不変なので、レデューサーはストアを更新する新しい更新状態を返しますここに画像の説明を入力してください

詳細については、フラックスvs Redux


複数のストアについて、Reduxで実行できるようになりました。react-reduxでは、ストアを分離するためのキーを追加できます:redux.js.org/faq/storesetup作業サンプル:github.com/Lemoncode/redux-multiple-stores
Braulio

6

私はFluxでかなり長い間働いていましたが、今ではReduxをかなり長い時間使っています。Danが指摘したように、両方のアーキテクチャはそれほど異なっていません。Reduxは物事をよりシンプルでクリーンにするということです。Fluxの上にいくつかのことを教えてくれます。たとえば、Fluxは一方向のデータフローの完璧な例です。データ、その操作、およびビューレイヤーが分離されている場合の懸念の分離。Reduxでも同じことが言えますが、不変性と純粋な関数についても学びます。


5

2018年半ばにExtJS(数年後)から移行する新しいreact / reduxアダプターから:

redux学習曲線を後方にスライドした後、同じ質問があり、純粋なフラックスはOPのように単純であると思いました。

上記の回答で述べたように、フラックスよりもreduxのメリットがすぐにわかり、それを最初のアプリに組み込んでいました。

ボイラープレートを再度把握している間に、他のいくつか状態管理ライブラリをいくつか試しましたが、私が見つけた最高のものはrematchでした。

それはバニラreduxよりもはるかに直感的であり、ボイラープレートの90%を削減し、redux(ライブラリーが行うべきだと思うこと)に費やしていた時間の75%を削減し、いくつかのエンタープライズアプリを取得できましたすぐに行く。

また、同じreduxツールで実行されます。これはいくつかの利点をカバーする良い記事です。

したがって、「簡単なredux」を検索してこのSOポストに到達した他の人は、すべての利点と定型の1/4を備えたreduxの単純な代替手段として試すことをお勧めします。


弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.