redux middleware 原始碼分析

2022-03-26 16:34:48 字數 2038 閱讀 7530

在業務中需要列印每乙個 action 資訊來除錯,又或者希望 dispatch 或 reducer 擁有非同步請求的功能。面對這些場景時,乙個個修改 dispatch 或 reducer **有些乏力,我們需要乙個可組合的、自由增減的外掛程式機制,redux 借鑑了 koa 中 middleware 的思想,利用它我們可以在前端應用中便捷地實現如日誌列印、非同步請求等功能。

比如在專案中,進行了如下呼叫後,redux 就整合了 thunk 函式呼叫以及列印日誌的功能。

import thunk from 'redux-thunk'

import logger from '../middleware/logger'

const store = createstore(rootreducer, enhancer)

下面追本溯源,來分析下原始碼。

export default function createstore(reducer, preloadedstate, enhancer) 

if (typeof enhancer !== 'undefined')

...}

return createstore => (...args) =>

// 序列 middleware

chain = middlewares.map(middleware => middleware(middlewareapi))

dispatch = compose(...chain)(store.dispatch)

return

}}

const middlewareapi = 

chain = middlewares.map(middleware => middleware(middlewareapi))

dispatch = compose(...chain)(store.dispatch)

觀察上述**後發現每個 middleware 都會傳入引數 middlewareapi,來看下中介軟體 logger 的原始碼 以及 redux-thunk 的原始碼, 發現中介軟體接受的第乙個引數正是 ()

// logger 原始碼

export default () => next => action =>

// redux-thunk 原始碼

export default () => next => action =>

return next(action) // 此處 next 為 logger 中介軟體返回的 (action) => {} 函式

}

接著上個小節,在dispatch = compose(...chain)(store.dispatch)中發現了 compose 函式,來看下 compose 的原始碼

export default function compose(...funcs)
compose 原始碼中的funcs.reduce((a, b) => (...args) => a(b(...args)))算是比較重要的一句,它的作用是返回組合引數後的函式,比如 compose(f, g, h) 等價於 (...args) => f(g(h(...args))),效果圖如下所示,呼叫 this.props.dispatch() 後,會呼叫相應的中介軟體,最終會呼叫 redux 原生的 store.dispatch(),並且可以看到中介軟體呼叫的形式類似資料結構中的棧(先進後出)。

拿上個小節提到的 logger、redux-thunk 中介軟體為例,其 middleware 的內部序列呼叫方式如下,從而完成了 dispatch 功能的增強(支援如this.props.dispatch(func)的呼叫以及日誌功能)。具體可以看 專案中的運用

action => 

return (action => )(action)

}

深入react技術棧

redux middleware 原始碼分析

在業務中需要列印每乙個 action 資訊來除錯,又或者希望 dispatch 或 reducer 擁有非同步請求的功能。面對這些場景時,乙個個修改 dispatch 或 reducer 有些乏力,我們需要乙個可組合的 自由增減的外掛程式機制,redux 借鑑了 koa 中 middleware 的...

Cartographer原始碼篇 原始碼分析 1

在安裝編譯cartographer 1.0.0的時候,我們可以看到 主要包括cartorgarpher ros cartographer ceres sover三個部分。其中,ceres solver用於非線性優化,求解最小二乘問題 cartographer ros為ros平台的封裝,獲取感測器資料...

AbstractListView原始碼分析3

normal list that does not indicate choices public static final int choice mode none 0 the list allows up to one choice public static final int choice ...