摘要:接下來我們來看看源碼中的模塊是怎么應用中間件的。如何實現(xiàn)中間件操作的。新的會從第一個中間件開始觸發(fā),這樣,在我們調(diào)用的時候,就會將中間件走一遍了。函數(shù)如果存在多個中間件,直接使用方法將各個中間件嵌套起來。
從redux-thunk引出思考
在使用redux-thunk進行異步action書寫的時候,我經(jīng)常好奇redux到底如何運作,讓asyncAction成為可能
為了探究,我們必須看一下redux-thunk的源碼了。幸運的是redux-thunk的源碼很少。。。至于為什么,下面立馬講解。
redux-thunk的源碼// redux-thunk source code 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;
從源碼可以看出該中間件僅僅只是一個工廠函數(shù),輸出了一個嵌套工廠函數(shù)的工廠函數(shù),那個最終參數(shù)帶著next的返回函數(shù),就是redux所需要適應的中間件。
以es6箭頭語法看來可能比較麻煩,我們可以試著把這個代碼直接轉(zhuǎn)成es5的形式看看。
function createThunkMiddleware(extraArgument) { return function (storeOrFakeStore) { var dispatch = storeOrFakeStore.dispatch; var getState = storeOrFakeStore.getState; return function (next) { return function (action) { return action(dispatch, getState, extraArgument); } return next(action); } }; }
從這個源碼可以看出,本身中間件是會接受當前store或者一個fakeStore(這個fakeStore可能僅僅只承載了store的兩個api,dispatch和getState),并將dispatch和getState這兩個store的方法傳進可能執(zhí)行異步操作的action函數(shù)里。這樣,action完成異步操作以后,同樣被賦予了dispatch的權(quán)利,就能夠?qū)顟B(tài)通過action流轉(zhuǎn)到下一個場景了。
那同學們又會問了,這個next是個啥?恩,其實這個next其實就是下一個要處理action的中間件,畢竟中間件是一個接著一個的對吧。如果大家寫過koa或者express應該對這個next會熟悉很多。
接下來我們來看看react源碼中的createStore模塊是怎么應用中間件的。
我們使用createStore api創(chuàng)建store的時候發(fā)生了什么applyMiddleware同樣也是一個工廠,如果讀者您用過redux中間件的話,你應該知道redux創(chuàng)建store是怎樣創(chuàng)建的
const store = createStore( reducer, applyMiddleware(...middleware) )
以下是createStore的源碼,我們只看相關的一部分
export default function createStore(reducer, preloadedState, enhancer) { if (typeof preloadedState === "function" && typeof enhancer === "undefined") { enhancer = preloadedState preloadedState = undefined } if (typeof enhancer !== "undefined") { if (typeof enhancer !== "function") { throw new Error("Expected the enhancer to be a function.") } return enhancer(createStore)(reducer, preloadedState) } ... }
結(jié)合store的聲明和使用,我們可以知道redux的第三個參數(shù)可以接受一個叫做增強器的東西,如果存在增強器,則直接調(diào)用增強器方法,返回新的store并增強redux的功能。而使用中間件的時候,redux將存在的applyMiddleware工廠方法作為增強器應用在了redux上。
applyMiddleware api如何實現(xiàn)中間件操作的。export default function applyMiddleware(...middlewares) { return (createStore) => (reducer, preloadedState, enhancer) => { const store = createStore(reducer, preloadedState, enhancer) let dispatch = store.dispatch let chain = [] const middlewareAPI = { getState: store.getState, dispatch: (action) => dispatch(action) } chain = middlewares.map(middleware => middleware(middlewareAPI)) dispatch = compose(...chain)(store.dispatch) return { ...store, dispatch } } }
applyMiddleware工廠函數(shù)對傳入的中間件進行了compose操作,使中間件互相之間呈嵌套的形式,這樣在中間件里的next函數(shù)就可以next()執(zhí)行下去了。。。新的dispatch會從第一個中間件開始觸發(fā),這樣,在我們調(diào)用store.dispatch的時候,就會將中間件走一遍了。
// compose函數(shù) export default function compose(...funcs) { if (funcs.length === 0) { return arg => arg } if (funcs.length === 1) { return funcs[0] } // 如果存在多個中間件,直接使用reduce方法將各個中間件嵌套起來。 // 于是我們在使用中間件的時候就要注意了,中間件本質(zhì)是一個攔截操作 // 如果我們有兩個中間件對某一個類型的action先后做了攔截,我們必須注意 // 在createStore的時候插入中間件的順序,中間件方法的執(zhí)行是有序的。 return funcs.reduce((a, b) => (...args) => a(b(...args))) }你也可以制作一個中間件
怎么樣,redux的源碼簡單嗎?簡單到同學們也能自己開發(fā)中間件,現(xiàn)在大家自己也可以動手寫自己的react中間件了。
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/84517.html
摘要:現(xiàn)在關于最新版本新特性的宣傳講解已經(jīng)鋪天蓋地了。測試場景是反復操作數(shù)組,這個反復操作有所講究,我們計劃持續(xù)不斷地改變數(shù)組的某一項而不是整個數(shù)組的大范圍變動。代碼和性能測試在使用開發(fā)時,相信很多開發(fā)者在搭配函數(shù)式的狀態(tài)管理框架使用。 現(xiàn)在關于 React 最新 v16 版本新特性的宣傳、講解已經(jīng)鋪天蓋地了。你最喜歡哪一個 new feature?截至目前,組件構(gòu)建方式已經(jīng)琳瑯滿目。那么,...
摘要:內(nèi)部機制探秘和文末附彩蛋和源碼這篇文章比較偏基礎,但是對入門內(nèi)部機制和實現(xiàn)原理卻至關重要。當然也需要明白一些淺顯的內(nèi)部工作機制。當改變出現(xiàn)時,相比于真實更新虛擬的性能優(yōu)勢非常明顯。直到最終,會得到完整的表述樹的對象。 React 內(nèi)部機制探秘 - React Component 和 Element(文末附彩蛋demo和源碼) 這篇文章比較偏基礎,但是對入門 React 內(nèi)部機制和實現(xiàn)原...
摘要:前端每周清單半年盤點之與篇前端每周清單專注前端領域內(nèi)容,以對外文資料的搜集為主,幫助開發(fā)者了解一周前端熱點分為新聞熱點開發(fā)教程工程實踐深度閱讀開源項目巔峰人生等欄目。與求同存異近日,宣布將的構(gòu)建工具由遷移到,引發(fā)了很多開發(fā)者的討論。 前端每周清單半年盤點之 React 與 ReactNative 篇 前端每周清單專注前端領域內(nèi)容,以對外文資料的搜集為主,幫助開發(fā)者了解一周前端熱點;分為...
摘要:前端日報精選劉海打理指北中的錯誤處理模式與反模式譯圖解和譯你并不知道中文裝飾器讓你的代碼更簡潔眾成翻譯第期每個程序員第一份工作前應該知道的件事中的不變性眾成翻譯寫的一次小結(jié)掘金內(nèi)部機制探秘和文末附彩蛋和源碼前端雜談開發(fā)實戰(zhàn) 2017-09-30 前端日報 精選 iPhone X 劉海打理指北React16中的錯誤處理ES6 Promise:模式與反模式「譯」圖解 ArrayBuffer...
摘要:使用新的易用的類定義,歸根結(jié)底也是要創(chuàng)建構(gòu)造函數(shù)和修改原型。首先,它把構(gòu)造函數(shù)當成單獨的函數(shù)且包含類屬性集。該節(jié)點還儲存了指向父類的指針引用,該父類也并儲存了構(gòu)造函數(shù),屬性集和及父類引用,依次類推。 原文請查閱這里,略有刪減,本文采用知識共享署名 4.0 國際許可協(xié)議共享,BY Troland。 本系列持續(xù)更新中,Github 地址請查閱這里。 這是 JavaScript 工作原理的第...
閱讀 678·2023-04-26 02:08
閱讀 2692·2021-11-18 10:02
閱讀 3495·2021-11-11 16:55
閱讀 2373·2021-08-17 10:13
閱讀 2928·2019-08-30 15:53
閱讀 710·2019-08-30 15:44
閱讀 2584·2019-08-30 11:10
閱讀 1785·2019-08-29 16:57