banner
SlhwSR

SlhwSR

热爱技术的一名全栈开发者
github
bilibili

redux中間ウェアの原理

一、何であるか#

ミドルウェア(Middleware)は、アプリケーションシステムとシステムソフトウェアの間にあるソフトウェアの一種であり、システムソフトウェアが提供する基本サービス(機能)を使用して、ネットワーク上のアプリケーションシステムのさまざまな部分や異なるアプリケーションを接続し、リソース共有や機能共有を実現することができます。

前の記事では、Reduxのワークフロー全体を理解しました。actionが発行されると、reducerがすぐにstateを計算します。このプロセスは同期的な操作です。

したがって、非同期操作をサポートしたり、エラー処理やログ監視をサポートしたりする場合、ミドルウェアを使用することができます。

Reduxでは、ミドルウェアはdispatchプロセス中に配置され、actionのディスパッチをインターセプトして処理します。以下の図を参照してください:

image

ミドルウェアは本質的には関数であり、store.dispatchメソッドを変更し、Actionの発行とReducerの実行の間に他の機能を追加します。

二、よく使用されるミドルウェア#

優れたreduxミドルウェアは多数あります。例えば:

  • redux-thunk:非同期操作に使用されます
  • redux-logger:ログの記録に使用されます

上記のミドルウェアはすべてapplyMiddlewaresを使用して登録する必要があります。これは、すべてのミドルウェアを配列にまとめて順番に実行するためのものです。

次に、createStoreに第 2 引数として渡すために、これを第 2 引数としてcreateStoreに渡します。

const store = createStore(
  reducer,
  applyMiddleware(thunk, logger)
);

redux-thunk#

redux-thunkは公式サイトで推奨されている非同期処理のミドルウェアです。

デフォルトのdispatch(action)では、actionは JavaScript のオブジェクトである必要があります。

redux-thunkミドルウェアは、渡されたデータの型をチェックし、関数である場合は(dispatch、getState)を関数に渡します。

  • dispatch 関数は、後でアクションを再度ディスパッチするために使用されます
  • getState 関数は、後の操作には元の状態に依存する必要があるため、以前の状態を取得できるようにします

したがって、dispatchは次のような関数として書くことができます:

const getHomeMultidataAction = () => {
  return (dispatch) => {
    axios.get("http://xxx.xx.xx.xx/test").then(res => {
      const data = res.data.data;
      dispatch(changeBannersAction(data.banner.list));
      dispatch(changeRecommendsAction(data.recommend.list));
    })
  }
}

redux-logger#

ログ機能を実装したい場合は、既存のredux-loggerを使用することができます。


import { applyMiddleware, createStore } from 'redux';
import createLogger from 'redux-logger';
const logger = createLogger();

const store = createStore(
  reducer,
  applyMiddleware(logger)
);

これにより、ミドルウェア関数を使用して簡単にログを記録できます。

三、実装原理#

まず、applyMiddlewaresのソースコードを見てみましょう。

export default function applyMiddleware(...middlewares) {
  return (createStore) => (reducer, preloadedState, enhancer) => {
    var store = createStore(reducer, preloadedState, enhancer);
    var dispatch = store.dispatch;
    var chain = [];

    var middlewareAPI = {
      getState: store.getState,
      dispatch: (action) => dispatch(action)
    };
    chain = middlewares.map(middleware => middleware(middlewareAPI));
    dispatch = compose(...chain)(store.dispatch);

    return {...store, dispatch}
  }
}

すべてのミドルウェアは配列chainに入れられ、ネストされて実行され、最後にstore.dispatchが実行されます。中間ウェア内部(middlewareAPI)では、getStatedispatchの 2 つのメソッドにアクセスできます。

上記の学習で、redux-thunkの基本的な使用方法を理解しました。

内部では、dispatchが判断され、対応する操作が実行されます。原理は次のようになります:

function patchThunk(store) {
    let next = store.dispatch;

    function dispatchAndThunk(action) {
        if (typeof action === "function") {
            action(store.dispatch, store.getState);
        } else {
            next(action);
        }
    }

    store.dispatch = dispatchAndThunk;
}

ログ出力を実現する原理も非常に簡単です。次のようになります:

let next = store.dispatch;

function dispatchAndLog(action) {
  console.log("dispatching:", addAction(10));
  next(addAction(5));
  console.log("新しいstate:", store.getState());
}

store.dispatch = dispatchAndLog;
読み込み中...
文章は、創作者によって署名され、ブロックチェーンに安全に保存されています。