對react中間件的理解
一、是什么?
中間件(Middleware
)在計算機中,是介于應(yīng)用系統(tǒng)和系統(tǒng)軟件之間的一類軟件,它使用系統(tǒng)軟件所提供的基礎(chǔ)服務(wù)(功能),銜接網(wǎng)絡(luò)應(yīng)用上的各個部分或不同的應(yīng)用,能夠達到資源共享、功能共享的目的
我們知道redux
整個工作流程,當action
發(fā)出之后,reducer
立即算出state
,整個過程是一個同步的操作。
那么如果要支持異步操作,或者支持錯誤處理、日志監(jiān)控,就可以使用上中間件。
Redux中,中間件就是放在就是在dispatch過程,在分發(fā)action進行攔截處理,如上圖
其本質(zhì)上一個函數(shù),對store.dispatch方法進行了改造,在發(fā)出 Action和執(zhí)行 Reducer這兩步之間,添加了其他功能
二、常用的中間件
redux-thunk
:用于異步操作
redux-logger
:用于日志記錄
redux-promise
redux-saga
上述的中間件都需要通過applyMiddlewares
進行注冊,作用是將所有的中間件組成一個數(shù)組,依次執(zhí)行,然后作為第二個參數(shù)傳入到createStore中
import { createStore, applyMiddleware } from 'redux' import thunk from 'redux-thunk' import createLogger rom 'redux-logger' const logger = createLogger() const store = createStore(reducer, applyMiddleware(thunk, logger)) // 按順序執(zhí)行 從右到左
logger實現(xiàn)
// 自己修改dispatch,增加logger let next = store.dispatch store.dispatch = function dispatchAndLog(action) { console.log('dispatching', action) next(action) console.log('next state', store.getState()) }
redux-thunk
添加了thunk中間件之后,就可以進行異步操作
redux-thunk是官網(wǎng)推薦的異步處理中間件
默認情況下的dispatch(action),action需要是一個JavaScript的對象
redux-thunk
中間件會判斷你當前傳進來的數(shù)據(jù)類型,如果是一個函數(shù),將會給函數(shù)傳入?yún)?shù)值(dispatch,getState)dispatch
函數(shù)用于我們之后再次派發(fā)actiongetState
函數(shù)考慮到我們之后的一些操作需要依賴原來的狀態(tài),用于讓我們可以獲取之前的一些狀態(tài)
所以dispatch可以寫成下述函數(shù)的形式:
const getHomeMultidataAction = () => { return (dispatch) => { axios.get("http://xxx.xx.xx.xx/test").then(res => { const data = res.data.data; dispatch(changeBannersAction(data.banner.list)); dispatch(changeRecommendsAction(data.recommend.list)); }) } }
dispatch(addTodo(text)) dispatch(addTodoAsync(text))
redux數(shù)據(jù)流圖:
三、實現(xiàn)原理
首先看看applyMiddlewares的源碼
export default function applyMiddleware(...middlewares) { return (createStore) => (reducer, preloadedState, enhancer) => { var store = createStore(reducer, preloadedState, enhancer); var dispatch = store.dispatch; var chain = []; var middlewareAPI = { getState: store.getState, dispatch: (action) => dispatch(action) }; chain = middlewares.map(middleware => middleware(middlewareAPI)); dispatch = compose(...chain)(store.dispatch); return {...store, dispatch} } }
所有中間件被放進了一個數(shù)組chain,然后嵌套執(zhí)行,最后執(zhí)行store.dispatch??梢钥吹?,中間件內(nèi)部(middlewareAPI)可以拿到getState和dispatch這兩個方法
在上面的學習中,我們了解到了redux-thunk的基本使用
內(nèi)部會將dispatch進行一個判斷,然后執(zhí)行對應(yīng)操作,原理如下:
function patchThunk(store) { letnext = store.dispatch; function dispatchAndThunk(action) { if (typeof action === "function") { action(store.dispatch, store.getState); } else { next(action); } } store.dispatch = dispatchAndThunk; }
實現(xiàn)一個日志輸出的原理也非常簡單,如下:
let next = store.dispatch; function dispatchAndLog(action) { console.log("dispatching:", addAction(10)); next(addAction(5)); console.log("新的state:", store.getState()); } store.dispatch = dispatchAndLog;
總結(jié)
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
React項目動態(tài)設(shè)置title標題的方法示例
這篇文章主要介紹了React項目動態(tài)設(shè)置title標題的方法示例,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2018-09-09React Router 如何使用history跳轉(zhuǎn)的實現(xiàn)
這篇文章主要介紹了React Router 如何使用history跳轉(zhuǎn)的實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2021-04-04react-navigation 如何判斷用戶是否登錄跳轉(zhuǎn)到登錄頁的方法
本篇文章主要介紹了react-navigation 如何判斷用戶是否登錄跳轉(zhuǎn)到登錄頁的方法,具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-12-12react-router browserHistory刷新頁面404問題解決方法
本篇文章主要介紹了react-router browserHistory刷新頁面404問題解決方法,非常具有實用價值,需要的朋友可以參考下2017-12-12