web-dev-qa-db-ja.com

Redux LOADING / SUCCESS / ERRORパターン-redux-sagaを使用する場合

一般的なWebアプリでは、通常、LOADING/SUCCESS/ERRORの問題に対処する必要があります。

  • ロードカーソルを表示したいバックエンドリクエストを行うとき、おそらくいくつかのボタンを無効にします。
  • リクエストが正常に終了したら、データを表示したいと思います。
  • リクエストがエラーで終了したとき-エラーを表示または処理したい。

注意しないと、これによりスパゲッティコードが発生する可能性があります。特に、2つのリクエストを同時に実行し、1つのリクエストが終了したときにそれを管理する場合、他のリクエストのロードカーソルは停止しません。たとえば、アイテム。

Reduxの場合のみ- このソリューションに出くわしました うまく機能することがわかりました。

基本的には、3つのアクションを定義します。

GET_FOO_REQUEST
GET_FOO_SUCCESS
GET_FOO_FAILURE

そして、すべての要求をインターセプトし、その特定の要求タイプ(この場合はGET_FOO)。

次に、それを必要とするコンポーネントのロード状態またはエラー状態を選択できます。

const loadingSelector = createLoadingSelector(['GET_FOO']);

const mapStateToProps = (state) => ({ isFetching: loadingSelector(state) });

私の質問は-redux-sagaを使用している場合-このパターンはまだ適切に適用されます-またはredux-sagaはすでにこの問題を解決していますか?

3
dwjohnston

はい、このパターンはredux sagaでうまく適用されます。

Redux sagaは、Redux内の単なるミドルウェアレイヤーと考えてください。基本的に、コードでアクションをディスパッチすると、redux sagaはそのアクションをインターセプトし、APIの呼び出しやデータの変更や他のアクションの呼び出しなどの非同期処理に使用できます。

したがって、この例の場合、GET_FOO_REQUESTをディスパッチするときは、そのアクションのためにサーガにリスナーを設定する必要があります。次に、saga関数は次​​のようになります。

  1. Reduxでロード状態を切り替えるディスパッチアクション
  2. APIリクエストを送信する
    • 成功した場合は、GET_FOO_SUCCESSをディスパッチします
    • エラーディスパッチの場合、GET_FOO_FAILURE

次に、GET_FOO_SUCCESS/FAILUREのレデューサーで、読み込み状態をオフに切り替えて、他に必要なことをすべて行う必要があります。

すべてのボイラープレートコードを自分で作成できますが、使用できる1つのクールなライブラリは redux-saga-routines です。この目的で、5つの異なるアクションタイプが自動的に作成されます。

  • routine.TRIGGER
  • routine.REQUEST
  • routine.SUCCESS
  • routine.FAILURE
  • routine.FULFIL

以下は、これらのアクションタイプを使用したサガの例です。

function* callAPI(action) {
  yield put(routine.REQUEST());
  try {
    const response = yield call(api, 'GET', '/foo/endpoint');
    yield put(routine.SUCCESS(response.data))

  } catch(err) {
      yield put(routine.FAILURE(err.message));

  } finally {
      yield put(routine.FULFILL());
  }

}
4
dane