web-dev-qa-db-ja.com

React Redux-Reducerに非同期メソッドを追加することはアンチパターンですか?

私は、react-native/reduxの世界全体がかなり新しいので、おそらくこの質問は馬鹿げているように聞こえるでしょう:)

API呼び出しなどの場合、ミドルウェアを使用するのが慣例ですが、常に必要ですか? (定型文がたくさん追加されます)。

アプリ内やローカル通知などのデバイスAPI接続を管理するために、レデューサーに非同期メソッドを正常に追加しましたが、この方法で処理しても問題ないかと思います。

たとえば、私のレデューサーにはこのメソッドがあります:

function initInApp(state, itemSkus){
  init(state, itemSkus);
  return {
    ...state,
    itemSkus: itemSkus,
  }
}

そして、これは非同期部分を管理します:

async function init(state, itemSkus){
  try {
    if( !state.isInit ){
      const prepare = await Promise.all(RNIap.prepareAndroid());
      return{
        ...state,
        isInit: true,
        errorCode: false,
      }
    }
    else {
       return ...state;
    }
  } catch (errorCode) {
    return{
      ...state,
      isInit: false,
      errorCode: errorCode,
      itemSkus: itemSkus
    }
  }
}

多分それはパフォーマンスの点で効率的ではないか、維持するのが難しい..これについてのあなたの考えは何ですか?

ありがとう:)

11
alan_langlois

はい。レデューサーにはanyの副作用があってはなりません。 reduxが効率的に機能するには、レデューサーが純粋な関数である必要があります。 reduxがレデューサーを純粋な関数である必要がある理由reduxで非常に重要な純粋なレデューサーである理由 を説明しようとする2つのリンクがあります。

他の人が指摘したように、サンクミドルウェアは反応の非同期を処理する一般的な方法です。

ライブラリを必要としないもう1つの方法は、「Fat Action Creators」と呼ばれるパターンを使用する方法です。アクション作成者は非同期操作を処理できます。これを行う方法は、関数の「ディスパッチ」ラッパーを返すことにより、それ自体がアクションをディスパッチできるようにすることです。

これは、Medium Articleからの例です。
ビジネスロジックをReact-Reduxアプリケーションのどこに置くか
(この記事は redux FAQ からもリンクされています):

const fetchUser = (dispatch, id) => {
  dispatch({ type: USER_FETCH, payload: id });
  axios.get(`https://server/user/${id}`)
   .then(resp => resp.data)
   .then(user => dispatch({ type: USER_FETCH_SUCCESS, 
                            payload: user }))
   .catch(err => {
     console.error(err); // log since might be a render err
     dispatch({ type: USER_FETCH_FAILED, 
                            payload: err, 
                            error: true });
   });
};

Redux-thunk以外のパッケージには、次のものがあります。

  • https://www.npmjs.com/package/redux-logic

    「すべてのビジネスロジックとアクションの副作用のための1つの場所」「redux-logicを使用すると、ロジックを好きなJSスタイルで自由に記述できます。

    • プレーンコールバックコード-dispatch(resultAction)
    • promises-return axios.get(url).then(...)
    • async/await-結果= fetch(url)を待つ
    • オブザーバブル-ob $ .next(action1) `
  • redux-saga

    redux-sagaは、アプリケーションの副作用(つまり、データフェッチのような非同期的なものや、ブラウザキャッシュへのアクセスのような不純なもの)を管理しやすく、実行効率が高く、テストが簡単で、障害の処理を改善することを目的とするライブラリです。 uses generators so make sure you're confortable using them

  • redux-observable 、RxJS Observableを使用する場合
    このライブラリはJay Phelpsによって作成され、この 中程度の投稿 "redux-observable" はBen Leshによって書かれました。反応コミュニティでよく知られている。

  • redux-thunk 完全を期すため。

  • 追加のパッケージは、前述の記事にリストされています。
    ビジネスロジックをReact-Reduxアプリケーションのどこに置くか

ではごきげんよう !

9
SherylHohman

反応中のレデューサーは、新しい状態を渡すことのみを目的としています。はい、API呼び出しやその他の「アクション」は、レデューサーでは実行されません。アンチパターンです。 react-thunkなどのさまざまな非同期アクションモジュールを使用して、非同期アクションを実行できます。

3
Chromonav

私が取り組んでいるプロジェクトでは、非同期コードを実行し、「サンク」と呼ばれる「ミドルウェア」を使用して、レデューサーが使用できるオブジェクトへのプロミスを解決します。すべてのレデューサーは、stateactionを取り、新しいstateを返す同期メソッドとして作成されます。

2
Code-Apprentice