124

ストアが独自の状態を維持し、その際にネットワークおよびデータ ストレージ サービスを呼び出す機能を備えている必要があります...その場合、アクションは単なるメッセージ パサーです。

-また-

...ストアは、アクションからの不変データの愚かな受信者であるべきですか (そして、アクションは外部ソース間でデータをフェッチ/送信するものである必要がありますか?このインスタンスのストアはビューモデルとして機能し、それらを集約/フィルタリングできますアクションによって供給された不変データに基づいて、独自の状態ベースを設定する前のデータ。

それは(両方の混合ではなく)どちらか一方であるべきだと私には思えます。もしそうなら、なぜ一方が他方よりも好まれる/推奨されるのですか?

4

6 に答える 6

151

I've seen the flux pattern implemented both ways, and after having done both myself (initially going with the former approach), I believe that stores should be dumb recipients of data from the actions, and that asynchronous processing of writes should live in the action creators. (Async reads can be handled differently.) In my experience, this has a few benefits, in order of importance:

  1. Your stores become completely synchronous. This makes your store logic much easier to follow and very easy to test—just instantiate a store with some given state, send it an action, and check to see if the state changed as expected. Furthermore, one of the core concepts in flux is to prevent cascading dispatches and to prevent multiple dispatches at once; this is very difficult to do when your stores do asynchronous processing.

  2. All action dispatches happen from the action creators. If you handle asynchronous operations in your stores and you want to keep your stores' action handlers synchronous (and you should in order to get the flux single-dispatch guarantees), your stores will need to fire additional SUCCESS and FAIL actions in response to asynchronous processing. Putting these dispatches in the action creators instead helps separate the jobs of the action creators and the stores; furthermore, you don't have to go digging through your store logic to figure out where actions are being dispatched from. A typical asynchronous action in this case might look something like this (change the syntax of the dispatch calls based on the flavor of flux you're using):

    someActionCreator: function(userId) {
      // Dispatch an action now so that stores that want
      // to optimistically update their state can do so.
      dispatch("SOME_ACTION", {userId: userId});
    
      // This example uses promises, but you can use Node-style
      // callbacks or whatever you want for error handling.
      SomeDataAccessLayer.doSomething(userId)
      .then(function(newData) {
        // Stores that optimistically updated may not do anything
        // with a "SUCCESS" action, but you might e.g. stop showing
        // a loading indicator, etc.
        dispatch("SOME_ACTION_SUCCESS", {userId: userId, newData: newData});
      }, function(error) {
        // Stores can roll back by watching for the error case.
        dispatch("SOME_ACTION_FAIL", {userId: userId, error: error});
      });
    }
    

    Logic that may otherwise be duplicated across various actions should be extracted into a separate module; in this example, that module would be SomeDataAccessLayer, which handles doing the actual Ajax request.

  3. You need less action creators. This is less of a big deal, but nice to have. As mentioned in #2, if your stores have synchronous action dispatch handling (and they should), you'll need to fire extra actions to handle the results of asynchronous operations. Doing the dispatches in the action creators means that a single action creator can dispatch all three action types by handling the result of the asynchronous data access itself.

于 2014-09-03T15:54:41.740 に答える
51

この質問を Facebook の開発者にツイートしたところ、Bill Fisher から得た回答は次のとおりです。

ユーザーの UI 操作に応答するとき、アクション クリエーター メソッドで非同期呼び出しを行います。

しかし、ティッカーやその他の人間以外のドライバーがいる場合は、店舗からの電話の方がうまく機能します。

重要なことは、データが常にアクションから発生するように、エラー/成功のコールバックでアクションを作成することです

于 2014-09-04T04:15:43.857 に答える
3

「愚かな」アクションを支持する議論を提供します。

アクションにビュー データを収集する責任を持たせることで、アクションをビューのデータ要件に結び付けることができます。

対照的に、ユーザーの意図、またはアプリケーションの何らかの状態遷移を宣言的に記述する一般的なアクションでは、そのアクションに応答する任意のストアが意図を、それにサブスクライブされたビュー専用に調整された状態に変換できます。

これは、より多くの、しかしより小さく、より専門的なストアに役立ちます。私がこのスタイルを支持する理由は、

  • これにより、ビューがストア データを消費する方法がより柔軟になります。
  • それらを消費するビューに特化した「スマート」ストアは、潜在的に多くのビューが依存する「スマート」アクションよりも小さく、複雑なアプリとの結合が少なくなります。

Store の目的は、ビューにデータを提供することです。「アクション」という名前は、その目的がアプリケーションの変更を説明することであることを示唆しています。

ウィジェットを既存のダッシュボード ビューに追加する必要があるとします。このビューには、バックエンド チームがロールアウトしたばかりの洗練された新しい集計データが表示されます。

「スマート」アクションでは、新しい API を使用するために「refresh-dashboard」アクションを変更する必要がある場合があります。ただし、抽象的な意味での「ダッシュボードの更新」は変わっていません。ビューのデータ要件が変更されました。

「ダム」アクションを使用して、新しいウィジェットが消費する新しいストアを追加し、「リフレッシュ ダッシュボード」アクション タイプを受け取ったときに新しいデータのリクエストを送信し、それを準備ができたら、新しいウィジェット。ビューレイヤーがより多くのデータまたは異なるデータを必要とする場合、私が変更するのはそのデータのソース、つまりストアであることは私には理にかなっています。

于 2015-10-11T05:15:44.820 に答える