Redux-middleware
Redux-ミドルウェア
Redux自体は同期なので、ネットワークリクエスト*などの *async 操作はReduxでどのように機能しますか ここでは、ミドルウェアが便利です。 前述のように、リデューサーはすべての実行ロジックが記述される場所です。 Reducerは、誰がそれを実行するか、アクションがディスパッチされる前と後のアプリの状態を取得または記録する時間とは関係ありません。
この場合、Reduxミドルウェア機能は、リデューサーに到達する前にディスパッチされたアクションと対話するための媒体を提供します。 カスタマイズされたミドルウェア関数は、高次関数(別の関数を返す関数)を作成することで作成できます。これは、いくつかのロジックをラップします。 複数のミドルウェアを組み合わせて新しい機能を追加することができ、各ミドルウェアは前後の知識を必要としません。 ミドルウェアは、ディスパッチされたアクションとレデューサーの間のどこかに想像できます。
一般に、ミドルウェアはアプリの非同期アクションを処理するために使用されます。 ReduxはapplyMiddlewareと呼ばれるAPIを提供します。これにより、redux-thunkやredux-promiseなどのReduxミドルウェアだけでなく、カスタムミドルウェアも使用できます。 ミドルウェアをストアに適用します。 applyMiddleware APIを使用する構文は次のとおりです-
applyMiddleware(...middleware)
そして、これは次のようにストアに適用することができます-
import { createStore, applyMiddleware } from 'redux';
import thunk from 'redux-thunk';
import rootReducer from './reducers/index';
const store = createStore(rootReducer, applyMiddleware(thunk));
ミドルウェアでは、アクションオブジェクトの代わりに関数を返すアクションディスパッチャを作成できます。 同じ例を以下に示します-
function getUser() {
return function() {
return axios.get('/get_user_details');
};
}
条件付きディスパッチはミドルウェア内に記述できます。 各ミドルウェアは、新しいアクションをディスパッチできるようにストアのディスパッチを受け取り、引数としてgetState関数を受け取り、現在の状態にアクセスして関数を返すことができます。 内部関数からの戻り値は、ディスパッチ関数自体の値として使用できます。
以下はミドルウェアの構文です-
({ getState, dispatch }) => next => action
getState関数は、現在の状態に応じて、新しいデータをフェッチするか、キャッシュ結果を返すかを決定するのに役立ちます。
カスタムミドルウェアロガー関数の例を見てみましょう。 アクションと新しい状態を記録するだけです。
import { createStore, applyMiddleware } from 'redux'
import userLogin from './reducers'
function logger({ getState }) {
return next => action => {
console.log(‘action’, action);
const returnVal = next(action);
console.log('state when action is dispatched', getState());
return returnVal;
}
}
次のコード行を記述して、ロガーミドルウェアをストアに適用します-
const store = createStore(userLogin , initialState=[ ] , applyMiddleware(logger));
以下のコードを使用して、ディスパッチされたアクションと新しい状態をチェックするアクションをディスパッチします-
store.dispatch({
type: 'ITEMS_REQUEST',
isLoading: true
})
ローダーを表示または非表示にするタイミングを処理できるミドルウェアの別の例を以下に示します。 このミドルウェアは、リソースを要求するときにローダーを表示し、リソースの要求が完了するとローダーを非表示にします。
import isPromise from 'is-promise';
function loaderHandler({ dispatch }) {
return next => action => {
if (isPromise(action)) {
dispatch({ type: 'SHOW_LOADER' });
action
.then(() => dispatch({ type: 'HIDE_LOADER' }))
.catch(() => dispatch({ type: 'HIDE_LOADER' }));
}
return next(action);
};
}
const store = createStore(
userLogin , initialState = [ ] ,
applyMiddleware(loaderHandler)
);