web-dev-qa-db-ja.com

reduxサンクディスパッチ後にストアからpromiseを返す

Reduxサンクでディスパッチをチェーンしようとしています

_function simple_action(){
  return {type: "SIMPLE_ACTION"}
}

export function async_action(){
  return function(dispatch, getState){
    return dispatch(simple_action).then(()=>{...});
  }
}
_

ストアから約束を返すためにディスパッチを取得するにはどうすればよいですか?

すなわち:

私はおそらくここで何かを理解していないだけかもしれませんが、_redux-thunk_のすべての例で、それらは別個の非同期イベント(fetchなど)を呼び出し、明らかにPromiseを返します。

特に探しているのは、ストアにアクションをディスパッチするときです。上記の関数action_creator()で他に何かが起こる前に、ストアがそのアクションを完全に処理したことを確認する方法です。

理想的には、ある種の約束を店に返してもらいたいのですが、それがどのように、どこで起こるのか分かりませんか?

39
l2silver

ここに、非同期アクションをディスパッチおよびチェーンする方法の例があります。 https://github.com/gaearon/redux-thunk

サンクミドルウェアは、サンク非同期アクションをアクションに変換する方法を知っているので、simple_action()をサンクにする必要があり、サンクミドルウェアはあなたのために仕事をします。ミドルウェアが通常のアクションを見ると、彼はこれをディスパッチします通常のアクションとしてのアクションですが、非同期関数の場合は、非同期アクションを通常のアクションに変換します。

そのため、simple_actionはサンクである必要があります(サンクは関数を返す関数です)。たとえば次のようになります。

function makeASandwichWithSecretSauce(forPerson) {
  return function (dispatch) {
    return fetchSecretSauce().then(
      sauce => dispatch(makeASandwich(forPerson, sauce)),
      error => dispatch(apologize('The Sandwich Shop', forPerson, error))
    );
  };
}

MakeASandwichWithSecretSauce関数を使用する場合、ディスパッチ関数を使用できます

store.dispatch(
  makeASandwichWithSecretSauce('Me')
);

そして

// It even takes care to return the thunk’s return value
// from the dispatch, so I can chain Promises as long as I return them.

store.dispatch(
  makeASandwichWithSecretSauce('My wife')
).then(() => {
  console.log('Done!');
});

ここでは、他のアクションクリエーターからアクションをディスパッチし、アクションを非同期化するアクションクリエーターを作成し、Promiseで制御フローを構築する方法の完全な例を示します。

function makeSandwichesForEverybody() {
  return function (dispatch, getState) {
    if (!getState().sandwiches.isShopOpen) {
      // You don’t have to return Promises, but it’s a handy convention
      // so the caller can always call .then() on async dispatch result.
      return Promise.resolve();
    }

    //Do this action before starting the next one below 
    dispatch(simple_action());

    // We can dispatch both plain object actions and other thunks,
    // which lets us compose the asynchronous actions in a single flow.
    return dispatch(
      makeASandwichWithSecretSauce('My Grandma')
    ).then(() =>
      Promise.all([
        dispatch(makeASandwichWithSecretSauce('Me')),
        dispatch(makeASandwichWithSecretSauce('My wife'))
      ])
    ).then(() =>
      dispatch(makeASandwichWithSecretSauce('Our kids'))
    ).then(() =>
      dispatch(getState().myMoney > 42 ?
        withdrawMoney(42) :
        apologize('Me', 'The Sandwich Shop')
      )
    );
  };
}
//apologize and withdrawMoney are simple action like this for example
      return {
        type:  "END_SUCESS"
      }

//使用法

store.dispatch(
  makeSandwichesForEverybody()
).then(() =>
    console.log("Done !");
);

独自の約束を作成するには、bluebirdのようなライブラリを使用できます。

//編集:アクションaction_creator()で何かが起こる前にストアがそのアクションを完全に処理したことを確認するには、action_creator()の前にこのsimple_actionをディスパッチできます。 //このコメントをコードに追加しました//Do this action before starting the next one below

27
Aaleks

dispatchは、呼び出すアクション/関数が返すものを返します。 (例のように)特定のアクティビティを連鎖させたい場合、アクションはPromiseを返す必要があります。

@Aaleksが言及しているように、アクションがthunkである場合、Promiseを返すシナリオを作成できます。その後、言及したとおりに実行できます。

ところで、thunkaction_creatorは、simple_actionは実際にはReduxの用語ではAction Creatorです-適宜編集してください

4
a darren

これは私が最近使用しているパターンです:

_export const someThenableThunk = someData => (dispatch, getState) => Promise.resolve().then(() => {
  const { someReducer } = getState();
  return dispatch({
    type: actionTypes.SOME_ACTION_TYPE,
    someData,
  });
});
_

dispatch(someThenableThunk('hello-world'))を実行すると、Promiseオブジェクトが返され、これをさらにアクションをチェーンできます。

3
Mapsy