49

Redux を使用している人々がバックエンドの永続化にどのように取り組んでいるのか疑問に思っています。特に、「アクション」をデータベースに保存していますか、それともアプリケーションの最新の既知の状態のみを保存していますか?

アクションを保存している場合、単純にサーバーにアクションを要求し、特定のページがロードされたときにすべてのアクションを再生しますか? これは、多くのアクションがある大規模なアプリでパフォーマンスの問題につながる可能性はありませんか?

「現在の状態」だけを保存している場合、クライアントでアクションが発生するときに、この状態を実際にどのように保持していますか?

Redux Reducer をバックエンド ストレージ API に接続する方法のコード例はありますか?

これが非常に「アプリに依存する」タイプの質問であることは承知していますが、ここでいくつかのアイデアを熟考し、この種の「ステートレス」アーキテクチャがフルスタックの意味でどのように機能するかを感じようとしています。

みんな、ありがとう。

4

2 に答える 2

36

レデューサーの状態を確実に保持してください!

代わりに一連のアクションを永続化した場合、prod データベース内をいじらずにフロントエンドでアクションを変更することはできません。

例: 1 つのレデューサーの状態をサーバーに永続化する

3 つの追加のアクション タイプから始めます。

// actions: 'SAVE', 'SAVE_SUCCESS', 'SAVE_ERROR'

私はredux-thunkを使用して非同期サーバー呼び出しを行います。これは、1 つのアクション クリエーター関数がdispatch追加のアクションを実行し、現在の状態を検査できることを意味します。

アクション作成者は、すぐに 1 つのsaveアクションをディスパッチします (UI でスピナーを表示したり、「保存」ボタンを無効にしたりできるようにするため)。POST リクエストが完了すると、ディスパッチSAVE_SUCCESSまたはアクションが実行されます。SAVE_ERROR

var actionCreators = {
  save: () => {
    return (dispatch, getState) => {
      var currentState = getState();
      var interestingBits = extractInterestingBitsFromState(currentState);

      dispatch({type: 'SAVE'});

      window.fetch(someUrl, {
        method: 'POST',
        body: JSON.stringify(interestingBits)
      })
      .then(checkStatus) // from https://github.com/github/fetch#handling-http-error-statuses
      .then((response) => response.json())
      .then((json) => dispatch actionCreators.saveSuccess(json.someResponseValue))
      .catch((error) =>
        console.error(error)
        dispatch actionCreators.saveError(error)
      );
    }
  },

  saveSuccess: (someResponseValue) => return {type: 'SAVE_SUCCESS', someResponseValue},

  saveError: (error) => return {type: 'SAVE_ERROR', error},

  // other real actions here
};

(NB$.ajaxは完全に代わりにwindow.fetch機能しますが、1つの関数に対してjQuery全体をロードしないことを好みます!)

レデューサーは、未処理のサーバー リクエストを追跡するだけです。

function reducer(state, action) {
  switch (action.type) {
    case 'SAVE':
      return Object.assign {}, state, {savePending: true, saveSucceeded: null, saveError: null}
      break;
    case 'SAVE_SUCCESS':
      return Object.assign {}, state, {savePending: false, saveSucceeded: true, saveError: false}
      break;
    case 'SAVE_ERROR': 
      return Object.assign {}, state, {savePending: false, saveSucceeded: false, saveError: true}
      break;

    // real actions handled here
  }
}

おそらく、サーバーから返された で何かをしたいと思うでしょうsomeResponseValue-多分それは新しく作成されたエンティティのIDなどです.

これが役に立てば幸いです。これまでのところうまく機能しています。

于 2015-10-10T14:37:08.627 に答える