Reduxミドルウェアメカニズムプローブ


原文住所:
https://monster1935.com/2019/...
状態管理案は以前にVuexに触れたことがあるだけで、Reactを使って開発する場合、React技術スタックの下の状態管理案を調査するのは避けられず、ReduxとMobxの関連流派があることを発見した.以下の内容はReduxのみについて説明します.
Reduxを使用する過程で、このようないくつかの知識点が受け入れやすいことがわかりました.
  • 状態の修正はdispatchの1つのactionを必要とし、状態の修正が制御可能で管理しやすいことを保証する
  • .
  • reducerは純粋な関数でなければなりません.stateを直接変更するのではなく、毎回新しいstateを返します.純関数の実現は運転効率を向上することができ、固定入力は固定出力
  • を生成する.
  • redux自体には「サブスクリプション」という概念があり、ステータスが変更されると、Reduxはサブスクライバを順次実行し、サブスクライバのイベントコールバック関数でstore.getState()を介して最新のステータス
  • を取得することができる.
    このとき,一つの同期についてのみ議論したが,いくつかの非同期および他の副作用のあるaction発生過程をどのように処理するかについて,この疑問を持って公式文書およびいくつかのDemo実装を見た.このプロセスにはredux−thunk,redux−promise,redux−sagaなどの処理スキームが現れた.これらはまた何をして、それぞれどんな問題を解決しましたか?
    これは、Reduxのミドルウェアメカニズムについて議論する.Reduxには、主にReduxのミドルウェアを登録するために使用されるAPI、applyMiddlewareがある.
    ドキュメントを読む過程で、主に最も基本的な世界観の問題を明らかにしました:Reduxのミドルウェアは何に使いますか?actionが開始された後、reducerに到達する前の拡張点を提供します.すなわち、以上で論じたredux-thunk、redux-promise、redux-sagaなどは、それぞれReduxのミドルウェアであり、使用時にはRedux createStoreに登録する必要があり、それぞれRedux dispatchの能力を強化している.同様に、これらのミドルウェアを適用した後に使用されるdispatchは、Redux本来のdispatchではなく、これらのミドルウェアによって書き換えられたdispatchであると理解できる.これにより、actionを生成する前に副作用のパッケージを作ることができます.
    redux−thunkを例にとると,この過程を明確に見ることができる.
    function createThunkMiddleware(extraArgument) {
      return ({ dispatch, getState }) => (next) => (action) => {
        if (typeof action === 'function') {
          return action(dispatch, getState, extraArgument);
        }
    
        return next(action);
      };
    }
    
    const thunk = createThunkMiddleware();
    thunk.withExtraArgument = createThunkMiddleware;
    
    export default thunk;
    

    以上redux-thunkというライブラリのソース部分ですが、「短くて精悍」という言葉はこのライブラリを形容するのに少しも過言ではありません.その実現を究明すると,redux−thunkというミドルウェアは主にdispatchのfunctionの能力を提供することが分かった.通常、Reduxのdispatchは純粋なjsオブジェクト、すなわちactionをdispatchすることができます.redux-thunkを使用すると、このfunctionが呼び出され、dispatchというパラメータに転送され、本当のdispatchがこのfunction内部で発生するfunctionを受信することができます.
    Reduxのミドルウェアメカニズムがどのように実現されるかについては,そのソースコードの実現を見た後,さらに巧みである.
    まず「ミドルウェア」という概念を明確にしなければならない.个人の下品な理解:中间件は1つの「パイプ」で、あなたがこの「パイプ」を过ぎて、いずれもこの「パイプ」に引き継がれて、「パイプ」は止めないで放さないで、あなたを「蹂躙」して何度もあなたを放して、もちろん「蹂躙」しないかもしれなくて、せいぜい戸籍(伝说の日志の中间件)を调べます.「蹂躙」されたものは精神的にも肉体的にも元のあなたと私ではなく、落ち込んでいるかもしれないし、奮発して強さを求めているかもしれない.
    以上の理解があれば、私たちがこのことを見ているうちに理解しやすくなります.複数のミドルウェアがあるかもしれませんが、この「屋」に入ると、これらのミドルウェアを順番に経験します.
    const reduxMiddleware = ({dispatch, getState}) => (next) => (action) => {
      //                 
      
      //   
      return next(action);
    }

    これはredux middlewareの一般的な実装です.applyMiddlewareで何があったの?
    const chain = middlewares.map(middleware => middleware({
      getState: store.getState,
      dispatch: (action, ...args) => dispatch(action, ...args),
    }));
    
    const dispatch = compose(chain)(store.dispatch);
    return {
      ...store,
      dispatch
    }
    

    大まかには、すべてのmiddlewareを転送し、composeという関数によってすべてのミドルウェアグループを統合してdispatchの関数に戻すことを意味します.このときのdispatchはreduxの元のdispatchではなく、ミドルウェアによって強化されたdispatchで、この中には制御権の反転があり、元のdispatch機能をパラメータとして転送します.関数内部でdispatchの論理を完了します.この場合のdispatchは次のようになります.
    
    const dispatch = (dispatch) => {
      // do things
      //                  
      // do things
      return action => dispatch(action);
    }
    

    Reduxミドルウェア実装の鍵はcompose関数であり、compose関数はArray.prototype.reduce() APIを利用して、すべてのミドルウェア関数の順次呼び出しを完了し、上述したような関数を返す.
    function compose(funcs) {
      return function (dispatch) {
        if (funcs.length === 1) {
          return funcs[0];
        }
        return funcs.reduce((a,b) => (...args) => a((b(...args))));
      }
    }
    

    以上がミドルウェアメカニズム全体の実現過程である.中にはいくつかの関数のコリー化の内容が含まれているため、いくつかの関数のネストが深くなってから戻ることができます.難解さを感じたら、この簡潔版のコードを見ることができます.
    //        
    const a = (next) => (action) => {
      console.log('    a       ');
      return next(action);
    };
    
    //        
    const b = (next) => (action) => {
      console.log('    b       ');
      return next(action);
    };
    
    //        
    const c = (next) => (action) => {
      console.log('    c       ');;
      return next(action);
    };
    
    //     dispatch
    var rawDispatch = (action) => {
      console.log('       dispatch action ,   : ', action);
      return action;
    }
    
    /**     applyMiddlware      ,         */
    var arr = [a, b, c];
    
    var res = arr.reduce((a, b) => (...args) => a(b(...args)));
    
    var enhanceDispatch = res(rawDispatch);
    
    
    //        dispatch,             
    enhanceDispatch('add');
    
    //     a       
    //     b       
    //     c       
    //         dispatch action ,   :  add
    // "add"
    

    参照リンク:
  • https://www.redux.org.cn/docs...