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