10

次の方法で複数のアクションを連鎖させようとしています。

A. ユーザーデータをデータベースに投稿する

B. 投稿されたデータを使用して Elasticsearch にクエリを実行し、結果を得る

(AとBを並行して行います)

B1. ES からの結果を使用して、元のデータベースに 2 つのテーブル B2 からの結果を照会します。新しいページに移動して UI を更新する

現在、サンクを使用してコードを推論していますが、この非同期パターンは非常に冗長であることがわかりました。

export function fetchRecipes(request) {
  return function(dispatch) {
    dispatch(requestRecipes(request))    
    return fetch(url)
      .then(response => response.json())
      .then(json => dispatch(receiveRecipes(request, json))
    )
  }
}

これは、「requestRecipes」と「receiveRecipes」とともに、他のアクション クリエーターが 1 つの非同期呼び出しを行うだけのように思えます。(リクエスト、レシーブ、フェッチ機能)

要約:出力が互いに依存する2〜3の非同期アクションをチェーンしている場合(可能な場合は約束する必要があります)、非同期呼び出しごとに3つの関数を作成せずにそうするより効率的な方法はありますか?

方法があったはずだと思います。私は Redux のドキュメントからパターン マッチングを行っていますが、作成していた関数にすぐに圧倒されてしまいました。

フィードバックをありがとう!

4

2 に答える 2

9

これをより簡単に達成するためredux-sagaに代わりに使用できます。ジェネレーターを使用して作業を説明でき、推論が容易になります。redux-thunkredux-saga

最初のステップは、サービスや非同期のものを気にせずにデータを redux に渡す方法を説明することです。

行動

// actions.js
function createRequestTypes(base) {
  return {
    REQUEST: base + "_REQUEST",
    SUCCESS: base + "_SUCCESS",
    FAILURE: base + "_FAILURE",
  }
}

// Create lifecycle types on `RECIPES`
export const RECIPES = createRequestTypes("RECIPES")

// Create related actions
export const recipes = {
  // Notify the intent to fetch recipes
  request: request => ({type: RECIPES.REQUEST, request})
  // Send the response
  success: response => ({type: RECIPES.SUCCESS, response})
  // Send the error
  error: error => ({type: RECIPES.FAILURE, error})
}

レデューサー

// reducer.js
import * as actions from "./actions"

// This reducer handles all recipes
export default (state = [], action) => {
  switch (action.type) {
    case actions.RECIPES.SUCCESS:
      // Replace current state
      return [...action.response]

    case actions.RECIPES.FAILURE:
      // Clear state on error
      return []

    default:
      return state
  }
}

サービス

レシピ API も必要です。サービスを宣言する最も簡単な方法を使用する場合redux-saga、リクエストを引数として読み取り、Promise.

// api.js
const url = "https://YOUR_ENPOINT";

export function fetchRecipes(request) {
  return fetch(url).then(response => response.json())
}

次に、アクションとサービスを関連付ける必要があります。ここでredux-saga出番です。

// saga.js
import {call, fork, put, take} from "redux-saga/effects"
import * as actions from "./actions"
import * as api from "./api"

function* watchFetchRecipes() {
  while (true) {
    // Wait for `RECIPES.REQUEST` actions and extract the `request` payload
    const {request} = yield take(actions.RECIPES.REQUEST)

    try {
      // Fetch the recipes
      const recipes = yield call(api.fetchRecipes(request))

      // Send a new action to notify the UI
      yield put(actions.fetchRecipes.success(recipes))
    } catch (e) {
      // Notify the UI that something went wrong
      yield put(actions.fetchRecipes.error(e))
    }
  }
}

function* rootSaga() {
  yield [
    fork(watchFetchRecipes)
  ]
}

以上です!コンポーネントがアクションを送信するたびRECIPES.REQUESTに、サガが接続され、非同期ワークフローが処理されます。

dispatch(recipes.request(req))

すばらしいのredux-sagaは、ワークフロー中に非同期効果を連鎖させてアクションをディスパッチできることです。

于 2016-04-18T06:44:36.993 に答える