理解Redux中間件

中間件是什么

如果你用過express.js之類的web框架,對中間件(Middleware)這個概念可能不會陌生。中間件其實就是一種獨立運行于各個框架組件之間的膠水代碼。在Express.js或Koa等框架中,中間件通常是運行在收到請求到處理請求之間,可是實現(xiàn)日志記錄、身份認(rèn)證等預(yù)處理操作。而在Redux里,中間件是運行在action發(fā)送出去,到達(dá)reducer之間的一段代碼。

編寫中間件

日志記錄是開發(fā)過程中常用的一個功能,你可以選擇侵入業(yè)務(wù)邏輯來記錄日志(不推薦),也可以選擇使用中間件來實現(xiàn)這個功能。接下來讓我們編寫一個常用的日志記錄中間件:

const loggerMiddleware = store => next => action => {
  console.group(action.type);
  console.log('action: ', action);
  const result = next(action);
  console.log('next state: ', store.getState());
  console.groupEnd(action.type);
  return result;
}

使用中間件的時候,要在初始化store的時候利用applyMiddleware注入進(jìn)去:

const store = createStore(
    rootReducer,
    applyMiddleware(loggerMiddleware)
)

這樣,我們在每次觸發(fā)action的時候就能記錄我們所需要的信息。同樣的方式,也可以實現(xiàn)日志上報等功能。

組合中間件

中間件其實是一種高層次的抽象,可以將核心領(lǐng)域業(yè)務(wù)和基礎(chǔ)架構(gòu)邏輯解耦開來。而多個中間件可以組合使用,從而使每一個中間件能夠保持“小而美”的特性。

const store = createStore(
    rootReducer,
    applyMiddleware(thunk, loggerMiddleware)
)

其中applyMiddleware函數(shù)可以接收多個中間件,源碼如下:

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
    }
  }
}

export default function compose(...funcs) {
  if (funcs.length === 0) {
    return arg => arg
  }

  if (funcs.length === 1) {
    return funcs[0]
  }

  const last = funcs[funcs.length - 1]
  const rest = funcs.slice(0, -1)
  return (...args) => rest.reduceRight((composed, f) => f(composed), last(...args))
}

我們可以看到它主要做了幾個工作:

  1. 返回一個高階函數(shù),這個函數(shù)中會初始化store和重寫dispatch邏輯,以便后續(xù)使用。
  2. store.getState,dispatch傳入每個中間件中,并收集調(diào)用鏈結(jié)果。

之后在應(yīng)用中所有使用的dispatch都將是修改過的邏輯,從中我們可以看出有點面向切面編程的味道,可以好好體會一下。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • “中間件”這個詞聽起來很恐怖,但它實際一點都不難。想更好的了解中間件的方法就是看一下那些已經(jīng)實現(xiàn)了的中間件是怎么工...
    Jmingzi_閱讀 1,786評論 1 7
  • 前言 最近幾天對 redux 的中間件進(jìn)行了一番梳理,又看了 redux-saga 的文檔,和 redux-thu...
    Srtian閱讀 33,716評論 9 40
  • redux的中間件相當(dāng)于改寫store的dispatch方法。redux-applyMiddleware源代碼 通...
    lcfme閱讀 617評論 1 0
  • 一、什么情況需要redux? 1、用戶的使用方式復(fù)雜 2、不同身份的用戶有不同的使用方式(比如普通用戶和管...
    初晨的筆記閱讀 2,138評論 0 11
  • 在學(xué)習(xí)了redux過程中,了解到中間件這個名詞,但是我看了十遍,也完全就是懵逼的狀態(tài)。于是又重復(fù)敲了幾次代碼也不能...
    綽號陸拾柒閱讀 600評論 0 0

友情鏈接更多精彩內(nèi)容