今天和大家聊一聊redux的中介軟體原理。
注:本文內容大部分參考redux的官網文件middleware - redux。如果英文好的同學可以直接閱讀官網文件,寫的非常好。
redux中介軟體提供了乙個切面的關注點。
我們可以很方便的利用中介軟體進行aop程式設計,比如日誌功能,埋點上報等。
這裡主要是利用裝飾器模式,在實際任務執行之前,動態新增before和after的邏輯。
這樣就能形成乙個洋蔥模型
接下來我們就看下如何手動開寫乙個日誌中介軟體
首先我們手動處理日誌,就是在執行dispatch方法前後,新增console.log
console.
log(
'dispatching'
, action)
store.
dispatch
(action)
console.
log(
'next state'
, store.
getstate()
)
手動處理日誌有一點問題,假如我們有多處執行action的地方需要用到日誌,我們不可能每一處都進行複製貼上。
那麼這時候就需要額外抽取乙個方法。
function
dispatchandlog
(store, action)
這樣我們只要對原來執行dispatch的地方替換為這個方法,就可以實現日誌功能了
dispatchandlog
(store,
addtodo
('use redux'
))
上一層的方法雖然解決了重複**的問題,但是還是需要我們修改所有的dispatch處。
這就會導致入侵業務**。
那有沒有非入侵的方式呢?有,就是monkeypatching。
monkeypatching,簡單的來說就是用自己定義的新方法,替換物件的原始方法。
這樣雖然業務**(使用方)沒有進行改動,但是實際的執行**已經在執行時被更改了。
const next = store.dispatch
store.
dispatch
=function
dispatchandlog
(action)
上一步我們解決了乙個中介軟體的問題,假如我們現在需要新增乙個新的中介軟體,那麼應該怎麼處理呢?
最簡單的方法是複製一遍邏輯。
let next = store.dispatch
store.
dispatch
=function
dispatchandlog1
(action)
next = store.dispatch
store.
dispatch
=function
dispatchandlog2
(action)
顯然,獲取next和賦值store.dispatch都是重複邏輯,應該抽取出來成為公共**.
假如我們做如下改動,直接返回包裝後的函式會如何?
function
logger
(store)
}
這樣我們就可以使用乙個foreach對乙個中介軟體陣列進行新增。
function
(store, middlewares)
ok,這個解決方案已經很棒了,但是我們還可以更進一步。
試想一下,我們在中介軟體**中,其實並不關心next方法是不是store.dispatch,只需要知道它能夠鏈式處理action即可。
那麼我們可以進一步隱藏這個概念。
const
logger
= store => next => action =>
function
(store, middlewares)
, store,
)}
這樣一來,我們在執行時,只要對乙個dispatch中間變數進行處理,最後再賦值在store即可。
在這裡我們看到了如何一步步實現乙個redux的中介軟體機制。
實際上,類似express,koa等後端框架的中介軟體機制也是用類似的方法進行處理的。
有了中介軟體,我們可以更方便的在非入侵業務**的情況下實現更多複雜的功能。
本文會經常更新,請閱讀個人部落格原文: ,以避免陳舊錯誤知識的誤導,同時有更好的閱讀體驗。
Redux入門0x105 redux 中介軟體
前一章講了redux的action creator,這一章講redux中很神奇的中介軟體。在專案中,我們經常會有記錄一些事件或者在某些事件發生的時候做某些事的需求,比如api介面鑑權操作 日誌記錄操作等,一般我們都可以用中介軟體來完成,中介軟體具有可拔插 可擴充套件的特點。我們也可以使用中介軟體來擴...
redux 中介軟體 redux thunk
什麼是中介軟體?中介軟體指的是redux的,不是react的。中間指的是action跟store之間,也就是對dispacth方的封裝,最原始的是直接將接受過來的物件直接傳遞給store,但是如果傳遞的是乙個函式的話,就不會將這直接傳遞給store,而是先執行這個函式。常見的中間有 redux de...
redux中介軟體原理
應用了如下的中介軟體 a,b,c 整個執行 action 的過程為 a b c dispatch c b a action 最右側的next action 返回的是應用傳入的action 該行為是由redux createstore原始碼中dispatch方法返回值決定的,不過一般都會return ...