摘要:的返回值是函數(shù),這個(gè)函數(shù)經(jīng)調(diào)用,傳入?yún)?shù),之后會(huì)在中間件鏈上進(jìn)行傳遞,只要保證每個(gè)中間件的參數(shù)是并且將傳遞給下一個(gè)中間件。
了解了Redux原理之后,我很好奇Redux中間件是怎么運(yùn)作的,于是選了最常用的redux-thunk進(jìn)行源碼分析。
此次分析用的redux-thunk源碼版本是2.2.0,redux源碼版本是3.7.2。并且需要了解Redux原理
redux中間件都是由redux的applyMiddleware()方法所掛載的
export default function applyMiddleware(...middlewares) { return (createStore) => (reducer, preloadedState, enhancer) => { const store = createStore(reducer, preloadedState, enhancer) let dispatch = store.dispatch let chain = [] //暴露給中間件的API,所以redux-thunk可以使用形如return (dispatch, getState)=>{} const middlewareAPI = { getState: store.getState, dispatch: (action) => dispatch(action) } //將暴露的API給中間件,調(diào)用中間件函數(shù),生成中間件返回值函數(shù)(為什么返回值是函數(shù)?不是函數(shù)下面的compose()就報(bào)錯(cuò)了) chain = middlewares.map(middleware => middleware(middlewareAPI)) //組合全部中間件的返回值函數(shù), chain是中間件返回值函數(shù)們 //然后reduce起來的函數(shù)返回的也是函數(shù),將store原來的dispatch傳進(jìn)去,dispatch函數(shù)也是接受一個(gè)action并返回一個(gè)action,作為中間件鏈的頭部 dispatch = compose(...chain)(store.dispatch) return { ...store, dispatch } } }
可以看到redux主要做了以下事情:
對(duì)中間件們使用map,將dispatch和getState傳遞進(jìn)去
使用compose將中間件組合起來,最后傳入原生的store.dispatch
而compose函數(shù)則是簡(jiǎn)單的將中間件進(jìn)行串聯(lián)調(diào)用
//compose(funcA, funcB, funcC) 等于 (args)=>funcA(funcB(funcC(args))) export default function compose(...funcs) { if (funcs.length === 0) { return arg => arg } if (funcs.length === 1) { return funcs[0] } return funcs.reduce((a, b) => (...args) => a(b(...args))) }
最后我們回到redux-thunk
redux-thunk的代碼很短,只有短短14行
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;
它對(duì)外暴露的是const thunk = createThunkMiddleware();,也就是({dispatch, getState})=>{...}這個(gè)函數(shù)。
然后經(jīng)chain = middlewares.map(middleware => middleware(middlewareAPI))傳入dispatch和getState,chain里面是next=>{...},進(jìn)行compose。
compose(a,b,c)的返回值是函數(shù)(...args)=>a(b(c(...args))),這個(gè)函數(shù)經(jīng)調(diào)用,傳入?yún)?shù)store.dispatch,之后action會(huì)在中間件鏈上進(jìn)行傳遞,只要保證每個(gè)中間件的參數(shù)是action并且將action傳遞給下一個(gè)中間件。
具體到redux-thunk中,它先檢查action是否是函數(shù),一般的action都是plain object,如果是函數(shù)就應(yīng)該是由thunk處理。如果不是,傳遞給next,next就是下一個(gè)中間件。
如果是函數(shù),則調(diào)用這個(gè)函數(shù)并將dispatch, getState, extraArgument傳入。這也就是為什么我們需要將thunk action生成函數(shù)(注意action和action生成函數(shù)的區(qū)別)寫成() => (dispatch, getState) => {...},傳入redux-thunk的action就是(dispatch, getState)=>{...}這個(gè)函數(shù)
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/89214.html
摘要:大多的初學(xué)者都會(huì)使用中間件來處理異步請(qǐng)求,其理解簡(jiǎn)單使用方便具體使用可參考官方文檔。源碼的源碼非常簡(jiǎn)潔,出去空格一共只有行,這行中如果不算上則只有行。官方文檔中的一節(jié)講解的非常好,也確實(shí)幫我理解了中間件的工作原理,非常推薦閱讀。 總覺得文章也應(yīng)該是有生命力的,歡迎關(guān)注我的Github上的博客,這里的文章會(huì)依據(jù)我本人的見識(shí),逐步更新。 大多redux的初學(xué)者都會(huì)使用redux-thunk...
摘要:然后循環(huán)調(diào)用中的更新函數(shù),更新函數(shù)一般是我們的渲染函數(shù),函數(shù)內(nèi)部會(huì)調(diào)用來獲取數(shù)據(jù),所以頁(yè)面會(huì)更新。前言 前幾天寫了一篇react另一個(gè)狀態(tài)管理工具Unstated的源碼解析。 開啟了我的看源碼之路。想一想用了好長(zhǎng)時(shí)間的redux,但從沒有深究過原理,遇到報(bào)錯(cuò)更是懵逼,所以就啃了一遍它的源碼,寫了這篇文章, 分享我對(duì)于它的理解。 API概覽 看一下redux源碼的index.js,看到了我們最...
摘要:然后循環(huán)調(diào)用中的更新函數(shù),更新函數(shù)一般是我們的渲染函數(shù),函數(shù)內(nèi)部會(huì)調(diào)用來獲取數(shù)據(jù),所以頁(yè)面會(huì)更新。 歡迎訪問個(gè)人網(wǎng)站:https://www.neroht.com/ 前言 前幾天寫了一篇react另一個(gè)狀態(tài)管理工具Unstated的源碼解析。開啟了我的看源碼之路。想一想用了好長(zhǎng)時(shí)間的redux,但從沒有深究過原理,遇到報(bào)錯(cuò)更是懵逼,所以就啃了一遍它的源碼,寫了這篇文章,分享我對(duì)于它的理...
摘要:核心源碼解析本文默認(rèn),你已經(jīng)有了一定的基礎(chǔ)。定義如何更新初始狀態(tài)是讓中間件按照規(guī)定模型洋蔥模型回形針模型執(zhí)行的函數(shù),就是下文將會(huì)介紹的函數(shù)的返回值返回中的。洋蔥模型回形針模型調(diào)用后的結(jié)果對(duì)上面的代碼換一種展現(xiàn)方式中間件要執(zhí)行,先得執(zhí)行。 redux 核心源碼解析 本文默認(rèn),你已經(jīng)有了一定的es6基礎(chǔ)。源碼有刪減,對(duì)其中的核心邏輯做解釋 redux 是 一個(gè)用 javascript 管...
摘要:接下來我們來看看源碼中的模塊是怎么應(yīng)用中間件的。如何實(shí)現(xiàn)中間件操作的。新的會(huì)從第一個(gè)中間件開始觸發(fā),這樣,在我們調(diào)用的時(shí)候,就會(huì)將中間件走一遍了。函數(shù)如果存在多個(gè)中間件,直接使用方法將各個(gè)中間件嵌套起來。 從redux-thunk引出思考 在使用redux-thunk進(jìn)行異步action書寫的時(shí)候,我經(jīng)常好奇redux到底如何運(yùn)作,讓asyncAction成為可能 為了探究,我們必須看...
閱讀 1814·2021-10-20 13:49
閱讀 1356·2019-08-30 15:52
閱讀 2863·2019-08-29 16:37
閱讀 1033·2019-08-29 10:55
閱讀 3064·2019-08-26 12:14
閱讀 1649·2019-08-23 17:06
閱讀 3235·2019-08-23 16:59
閱讀 2543·2019-08-23 15:42