Redux中間件的使用方法教程
前言
- 在Express框架中,middleware是指可以被嵌入在框架接收請(qǐng)求到產(chǎn)生響應(yīng)過程中的代碼。
- 在Redux中,middleware提供的是位于action被發(fā)起后,到達(dá)reducer之前的擴(kuò)展點(diǎn)
Q: 中間件的代碼什么時(shí)候被調(diào)用?
A: 在 action 被發(fā)起之后,到達(dá) reducer 之前。
下面用流程圖來解釋middleware:
應(yīng)用
如何創(chuàng)建一個(gè)中間件
首先,Redux中間件的形式為一個(gè)柯里化的函數(shù)。
function exampleMiddleware(storeAPI) { return function wrapDispatch(next) { return function handleAction(action) { // 在這里做你想做的事情,做完后,通過返回next(action)向下一個(gè)middleware傳遞action return next(action) } } }
- 最外層的
exampleMiddleware
函數(shù)將會(huì)被applyMiddleware
直接調(diào)用,并傳入一個(gè)包含dispatch()
和getState()
的對(duì)象作為參數(shù) - 調(diào)用
storeAPI.dispatch(action)
時(shí),它會(huì)將操作發(fā)送到中間件鏈的開頭,重新執(zhí)行所有的中間件 - 中間層的
wrapDispatch
函數(shù)接收一個(gè)名為next
的函數(shù)作為其參數(shù)。這個(gè)函數(shù)實(shí)際上是中間件鏈中的下一個(gè)中間件。如果這個(gè)中間件是序列中的最后一個(gè),那么next
函數(shù)實(shí)際上是原始的store.dispatch
函數(shù)。調(diào)用next(action)
會(huì)將action
傳遞給中間件鏈中的下一個(gè)中間件 - 最后,
handleAction
函數(shù)接收當(dāng)前action
作為其參數(shù),并在每次dispatch(action)
時(shí)調(diào)用
可以使用ES6的箭頭函數(shù)簡化此函數(shù):
const exampleMiddleware = store => next => action => { return next(action) }
如何應(yīng)用中間件
Redux 中間件實(shí)際上是在 Redux 內(nèi)置的一個(gè)非常特殊的存儲(chǔ)增強(qiáng)器之上實(shí)現(xiàn)的,稱為 applyMiddleware。
import { createStore, applyMiddleware } from 'redux' import rootReducer from './reducer' import { print1, print2, print3 } from './exampleAddons/middleware' const middlewareEnhancer = applyMiddleware(print1, print2, print3) const store = createStore(rootReducer, middlewareEnhancer) export default store
原理
Redux 如何裝載Middleware
相關(guān)源碼:
applyMiddleware和Compose函數(shù)的執(zhí)行過程:
// 省略了中間代碼并去除typescript類型,并將Compose和applyMiddleware函數(shù)放在一起便于展示 function compose(...funcs) { // 沒有傳入middleware,直接返回 if (funcs.length === 0) { return (arg) => arg } // 傳入一個(gè)middleware,無需構(gòu)造,直接返回 if (funcs.length === 1) { return funcs[0] } // 進(jìn)行函數(shù)柯里化返回一個(gè)形如:fn1(fn2(fn3(store.dispatch))) 的新dispatch函數(shù) return funcs.reduce( (a, b) => (...args: any) => a(b(...args)) ) } function applyMiddleware(...middlewares){ return (createStore) => (reducer, preloadedState) => { // createStore中檢測到由applyMiddleware函數(shù)生成的enhancer時(shí),將createStore、reducer、initialState傳入,在函數(shù)中創(chuàng)建一個(gè)臨時(shí)的store const store = createStore(reducer, preloadedState) // 創(chuàng)建一個(gè)臨時(shí)的dispatch函數(shù),此函數(shù)拋出異常,用于防止處理傳入的middlewares時(shí)提前調(diào)用dispatch let dispatch = () => { throw new Error( 'Dispatching while constructing your middleware is not allowed. ' + 'Other middleware would not be applied to this dispatch.' ) } // 給middleware分發(fā)store const middlewareAPI = { getState: store.getState, dispatch: (action, ...args) => dispatch(action, ...args) } // 讓每個(gè)middleware帶著middlewareAPI這個(gè)參數(shù)執(zhí)行一遍,然后獲得帶著相同的store的middlewares const chain = middlewares.map(middleware => middleware(middlewareAPI)) // 將所有chain中的函數(shù)利用Compose函數(shù)組裝成一個(gè)新的dispatch函數(shù) // 如:dispatch=fn1(fn2(fn3(store.dispatch))) dispatch = compose(...chain)(store.dispatch) // 將生成的dispatch函數(shù)整合到剛才生成的store中并返回 return { ...store, dispatch } } }
當(dāng)我們調(diào)用store.dispatch(action)
時(shí),我們實(shí)際上是在調(diào)用管道中的第一個(gè)中間件。然后,該中間件可以在收到action
時(shí)做任何它想做的事情,并在做完該事情后將action
傳給下一個(gè)中間件繼續(xù)處理,直到所有中間件處理完成,調(diào)用原始的dispatch
函數(shù)將action
提交給reducer
處理引發(fā)state
變化
到此這篇關(guān)于Redux中間件的使用方法教程的文章就介紹到這了,更多相關(guān)Redux中間件內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
react echarts tooltip 區(qū)域新加輸入框編輯保存數(shù)據(jù)功能
這篇文章主要介紹了react echarts tooltip 區(qū)域新加輸入框編輯保存數(shù)據(jù)功能,大概思路是用一個(gè)div包裹echarts, 然后在echarts的同級(jí)新建一個(gè)div用來用來模擬真實(shí)tooltip,通過鼠標(biāo)移入移出事件控制真實(shí)tooltip的顯示與隱藏,需要的朋友可以參考下2023-05-05React項(xiàng)目中hook實(shí)現(xiàn)展示對(duì)話框功能
Modal(模態(tài)框)是 web 開發(fā)中十分常見的組件,即從頁面中彈出的對(duì)話框,下面這篇文章主要給大家介紹了關(guān)于React項(xiàng)目中hook實(shí)現(xiàn)展示對(duì)話框功能的相關(guān)資料,需要的朋友可以參考下2022-05-05深入學(xué)習(xí)TypeScript 、React、 Redux和Ant-Design的最佳實(shí)踐
這篇文章主要介紹了深入學(xué)習(xí)TypeScript 、React、 Redux和Ant-Design的最佳實(shí)踐,TypeScript 增加了代碼的可讀性和可維護(hù)性,擁有活躍的社區(qū),,需要的朋友可以參考下2019-06-06React利用props的children實(shí)現(xiàn)插槽功能
React中并沒有vue中的?slot?插槽概念?不過?可以通過props.children?實(shí)現(xiàn)類似功能,本文為大家整理了實(shí)現(xiàn)的具體方,需要的可以參考一下2023-07-07React啟動(dòng)時(shí)webpack版本沖突報(bào)錯(cuò)的解決辦法
在啟動(dòng)React應(yīng)用時(shí),遇到Webpack版本不匹配導(dǎo)致的運(yùn)行錯(cuò)誤,解決方法包括刪除全局及局部的webpack和webpack-cli,然后根據(jù)項(xiàng)目需求安裝特定版本的webpack,本文通過代碼示例給大家介紹的非常詳細(xì),需要的朋友可以參考下2024-09-09react?hooks中的useState使用要點(diǎn)
這篇文章主要為大家介紹了react?hooks中的useState使用要點(diǎn)詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-09-09react源碼層分析協(xié)調(diào)與調(diào)度
本文主要介紹了深入理解React協(xié)調(diào)與調(diào)度(Scheduler)原理,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)吧2022-10-10react ant-design Select組件下拉框map不顯示的解決
這篇文章主要介紹了react ant-design Select組件下拉框map不顯示的解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-03-03