高低を検索しましたが、明確な答えが見つかりません。
私はなんとかReduxの仕組みに頭を悩ませましたが、しかしAPI呼び出しと非同期アクションの作成者のところに来たとき、私はミドルウェアで立ち往生していますPromisesのコンテキスト。
私が混乱を正しくするのを手伝ってくれませんか?
私に頭痛を与えるパズルの矛盾した部分:
YTチュートリアルの1つは、ネイティブのReduxディスパッチメソッドはアクションクリエーターから返されたプロミスをサポートしないと言っています-したがって、Redux Promiseライブラリの必要性(プロジェクトはおそらく今死んでいて、継続はReduxですPromiseミドルウェア)。
ダンは「 redux-thunkとredux-promiseの違いは何ですか? "ミドルウェアがなくてもpromiseを使用できます-アクションクリエーターで管理するだけです。
他の回答では、アクション作成者が返したサンクの使用例を見つけました... promise(後で呼び出し元/dispatch(myActionCreator(params).thenで処理されました) (...)/だからpromise canサンクによって返される[〜#〜] without [〜#〜] redux-promise lib ..?
「 redux-thunkとredux-promiseの違いは何ですか? 」では、受け入れられた回答はRedux Thunkが関数を返すのに対し、ReduxPromiseはpromiseを返すと述べています。
まとめ:ReduxPromiseまたはReduxPromiseミドルウェアを使用する意味は何ですか? Reduxだけがpromiseをネイティブにサポートしないのはなぜですか?
更新:
上記のポイント3で、then()
がdispatch
に添付であり、dispatch()
引数に含まれているではないことを見落としていることに気づきました。 。
リンクされた答えは正しいですが、私はさらに説明しようとします。
基本的なReduxストアはonlyプレーンオブジェクトアクションのディスパッチを受け入れます。
_store.dispatch({type : "ADD_TODO", text : "Buy milk"});
_
プレーンオブジェクトアクション以外のものを渡そうとすると、ストアはエラーをスローします。
_store.dispatch(() => {});
// Error: "Actions must be plain objects. Use custom middleware for async actions."
_
ミドルウェアはstore.dispatch()
の周りにパイプラインを形成し、各ミドルウェアはdispatch
に渡された値を使用して必要なことをすべて実行できます: 変更、ログ記録、遅延、または代わりに何か他のものをディスパッチします 。つまり、ミドルウェアは、値をインターセプトして代わりに他のことを行うことにより、notプレーンアクションオブジェクトであるものを受け入れる方法をdispatch()
に「教える」ことができます。 。
したがって、_redux-thunk
_は、関数をインターセプトし、レデューサーに渡す代わりに呼び出すことによって、関数を受け入れる方法をdispatch
に「教えます」。 _redux-promise
_ "teaches" dispatch
promiseをインターセプトし、promiseが解決または拒否されたときにアクションをディスパッチすることにより、promiseを受け入れる方法。
通常、dispatch
は渡されたアクションオブジェクトを返します。ミドルウェアはdispatch
をラップアラウンドするため、返される値を変更することもできます。 _redux-thunk
_はサンク関数を実行し、そのサンク関数が返すものをすべて返します。これにより、サンクからpromiseを返す、そこから動作を連鎖させるなどの便利なことができます。
_dispatch(someThunkReturningAPromise())
.then(() => {
// Do more stuff here
});
_
このトピックの詳細については、 Redux FAQ副作用の処理に関するエントリ )および Reduxの記事を参照してください。副作用 私の React/Reduxリンクリスト のセクション。
アクションクリエーター関数の最初の行の1つであるアクションクリエーターを呼び出すと、ajaxリクエストが行われます。これは、そのJSONAPIに到達するネットワークリクエストです。
理解しておくべき重要な部分は、その要求を行うと、次のコード行に移動して、そのアクションオブジェクトを作成し、それを返すことです。これらの2つのステップの間、要求を行ってからアクションを返すまでの時間は瞬時に発生します。
ご存知のとおり、外部APIにネットワークリクエストを送信すると、応答が返されるまでに時間がかかる場合があります。
したがって、アクション作成者からアクションを返した後、将来のある時点で、JSONAPIから応答が返されます。
そのため、発行されたAjaxリクエストとアクションクリエーターから返されるアクションの間は瞬時に発生する可能性がありますが、アクションクリエーターからアクションが返されるまでの時間とJSONAPIからの応答が受信されるまでの時間は長くなる可能性があります。
所要時間に関係なく、アクションがレデューサー内に表示されるまでに、APIからデータを常に利用できるようになります。
より良いアイデアを提供するために、私は自分のレデューサーの1つにdebugger
ステートメントを追加して、その中のさまざまな値を確認できるようにしました。
import { SAVE_COMMENT, FETCH_COMMENTS } from 'actions/types';
export default function(state = [], action) {
switch (action.type) {
case SAVE_COMMENT:
return [...state, action.payload];
case FETCH_COMMENTS:
debugger;
const comments = action.payload.data.map(comment => comment.name);
return [...state, ...comments];
default:
return state;
}
}
[コメントを取得]ボタンをクリックすると、アクションクリエーターが呼び出され、[ソース]タブ内で、すぐにdebugger
ステートメントが表示されます。
これは、このアクションがレデューサー内に表示されるたびに、APIから取得した応答があるという証拠です。
それでは、Redux Promiseミドルウェアを削除して、何が起こるか見てみましょう。
ミドルウェア:
export default ({ children, initialState = {} }) => {
const store = createStore(
reducers,
initialState,
applyMiddleware(reduxPromise)
);
ミドルウェアがなくなった:
export default ({ children, initialState = {} }) => {
const store = createStore(reducers, initialState, applyMiddleware());
return <Provider store={store}>{children}</Provider>;
};
これは何ですか?
payload
はJSONAPIから返される応答ではなく、保留中のPromise
です。これは、JSONAPIから返されるのを待っているネットワーク上でリクエストがまだ送信されていることを意味します。明らかに、Redux Promiseミドルウェアがないと、アプリケーションは期待どおりに機能しません。
アクションクリエーターは非同期リクエストをサポートするように開発されていませんでした。それを監視と呼んでください。
Redux Promiseなどのミドルウェアを使用して、レデューサーに送信されようとしているアクションを確認します。アクションを完全に遅延、ログ記録、変更、または停止する機会があります。これらのミドルウェアを介してのみ、これらの非同期リクエストを機能させることができます。私たちはそれを期待しています。 Redux Promiseを使用しているのは、アクションクリエーターから返されたすべてのアクションを検査し、APIリクエストまたは非同期リクエストが含まれている場合はそれを遅らせて、アクションが続行される前にそのレスポンスが返されるようにするためです。レデューサー。それがReduxPromiseが私たちのために行っていることです。
javascriptは非同期であるため、競合状態を回避するためにこれらのミドルウェアが必要です。それらの違いは、実装、関数を使用したサンク、ジェネレーターを使用したサガなどです。