這期內容當中小編將會給大家帶來有關如何使用Redux中間件,文章內容豐富且以專業的角度為大家分析和敘述,閱讀完這篇文章希望大家可以有所收獲。
為什么要使用中間件
在利用Redux進行狀態管理時,用戶在UI層面觸發行為,一個action對象通過store.dispatch派發到Reducer進行觸發,接下來Reducer會根據type來更新對應的Store上的狀態樹,更改后的state會觸發對應組件的重新渲染。如下圖所示。在這個流程中,action對象是一個同步的對象,是一個包含type字段的簡單對象,但是在訪問服務器時,由于瀏覽器是單線程的,不會一遍渲染組件一遍等待服務器返回的結果,因此我們需要設計一種異步訪問服務器的方法來實現與服務器端的正常通信。
中間件介紹
在Redux架構下,一個action對象在通過store.dispatch派發,在調用reducer函數前,會先經過一個中間件環節,如下圖所示。
從上圖可以看出,在一個Redux架構中可以用多個中間件,這些中間件一起組織處理請求的“管道”。一個中間件是一個獨立的函數,可以組合使用,中間件有一個統一的接口,正因為一個中間件只能完成一個特定的功能,所以把多個中間件組合在一起才能滿足比較豐富的應用需求。當然在使用時,也需要按照順序依次處理傳入的action,只有排在前面的中間件完成任務之后,后面的中間件才能有機會繼續處理action。
中間件的特點
中間件是獨立的函數
中間件可以組合使用
中間件有一個統一的接口
中間件接口
每個中間件必須定義為一個函數,返回一個接受next參數的函數,而這個接受next參數的函數又返回一個接受action參數的函數。next參數本身也是一個函數,中間件調用這個next函數通知Redux自己的處理工作已經結束。
一個什么都不做的中間件代碼如下:
function doNothingMiddleware({dispatch, getState}) { return function(next){ return function(action){ return next(action); } } }
包含的功能有:
調用dispatch派發出一個新的action對象
調用getState獲得當前Redux Store上的狀態
調用next告訴Redux當前中間件工作完畢,讓Redux調用下一個中間件
訪問action對象action上的所有數據
在一個Redux應用如果想要使用中間件,必須通過applyMiddleware來生成。Redux的源碼文件非常簡單,由五個文件一起組成,分別是createStore.js,applyMiddlware.js,compose.js,bindActionCreator.js,combineReducers.js。與createStore是用來創建一個狀態樹,并且暴露出幾個方法,包括dispatch,subscribe,getState,replaceReducer和$$observable,給createStore傳入的參數有reducer,preloadedState和enhancer,其中enhancer就是一個store增強器,是一個函數,只能用applyMiddleware生成。applyMiddleware函數是根據外部函數(中間件函數)包裝原來的dispatch函數,然后將新的dispatch函數暴露出去。
//根據外部函數(中間件函數)包裝原來的dispatch函數,然后將新的dispatch函數暴露了出去 export default function applyMiddleware(...middlewares) { //return一個函數,它可以接受createStore方法作為參數,給返回的store的dispatch方法再進行一次包裝 return createStore => (...args) => {//agrs包含reducer, preloadedState, enhancer const store = createStore(...args) let dispatch = () => { throw new Error( `Dispatching while constructing your middleware is not allowed. ` + `Other middleware would not be applied to this dispatch.` ) } //暴露兩個方法給外部函數 const middlewareAPI = { getState: store.getState, dispatch: (...args) => dispatch(...args) } //傳入middlewareAPI參數并執行每一個外部函數,返回結果匯聚成數組 const chain = middlewares.map(middleware => middleware(middlewareAPI)) //這里用到了compose方法 dispatch = compose(...chain)(store.dispatch) return { ...store, dispatch } } }
中間件與增強器的區別
中間件和增強器都是對Redux Store的增強,但是中間件僅僅是對Redux Store的dispatch方法進行了增強,也就是從dispatch函數調用到action對象被reducer處理這個過程中的操作,增強器是對Redux Store進行更深層次的增強定制,需要使用Store Enhancer,通過閱讀增強器接口,一個增強器其實利用隨給的參數創造出一個store對象,然后定制對象,最后把Store對象返回??偟膶Ρ热缦拢?/p>
中間件: 可以用來增強redux store的dispatch函數,也就是從dispatch函數調用到action對象被reducer處理這個過程中的操作
增強器: 對redux store進行更深層次的增強定制,可以增強redux store的各個方面。
異步訪問服務器:
異步action對象
在沒有引入中間件時,社會治理子系統在開發時,所有的action都是同步的,一個同步的action對象是一個包含type字段的簡單對象,但是我們需要實現一個異步action對象,是一個函數,在action觸發之后,在reducer接收到執行命令之前可以進行一個異步操作。
我們引入redux-thunk來實現異步訪問服務器方法,一個訪問服務器的action,至少要涉及三個action類型:
表示異步操作已經開始的action類型;
表示異步操作成功的action類型;
表示異步操作失敗的action類型;
Redux-thunk源代碼解析
Redux-thunk中間件是Redux中異步操作的解決方法之一,在action對象被reducer函數處理之前,是插入異步功能的時機,代碼非常簡單:
function create ThunkMiddleware(extraArgument){ return ({dispatch, getState}) => next => action => { if(typeof action === ‘function'){ return action(dispatch, getState, extraArgument); } return next(action) } } const thunk = createThunkMiddleware(); export default thunk;
createThunkMiddleware函數返回了一個函數,是實際處理每個action對象的函數,首先檢查參數action的類型,如果是函數類型的話,就執行這個action函數,把dispatch和getState
作為參數傳遞出去,否則就調用next讓下一個中間件繼續處理action。
Redux-thunk的使用:
首先,安裝redux-thunk,在已經安裝了node.js的命令窗口中運行 “npm install redux-thunk --save-dev”,在store.js中引入redux-thunk,并且確保redux的applyMiddleware函數也引入。具體實現代碼如下。
import {createStore, combineReducers, applyMiddleware} from ‘redux'; import {otherState, dataState} from ‘reducers'; import thunkMiddleware from ‘redux-thunk'; var reducers = combineReducers({ otherState, dataState }); var store = createStore(reducers, applyMiddleware(thunkMiddleware)); export default store;
在成功引入了redux-thunk后,我們也要設計異步操作的action對象,例如,在設備管理模塊中,成功保存設備信息后要重新獲取設備信息,代碼如下:
function saveInfo(params){ let url = “/api/device”; return function(dispatch, getState){ dispatch(saveInfoRequest()); return Http.get(url, { params: params }).then(res=>{ if(res && res.type === 0){ dispatch(saveInfoSuccess ()); let dataState = getState().dataState; let newParams = { start: dataState.start, limit: dataState.limit, searchName: dataState.searchName }; dispatch(getInfo(newParams)) } }).catch(error=>{ dispatch(saveInfoFailure (error)); }); } }
從這個saveDeviceInfo返回的函數中,不僅可以dispatch一個同步的action對象,還可派發另一個異步action對象,來滿足一些有著先后關系的業務邏輯,代碼可讀性要比用Promise實現起來代碼更加清晰。
Redux-logger使用
在開發階段,我們需要對redux數據流中每個流程進行監控,需要log輸出,redux-logger是官方推薦的一款日志中間件,使用起來非常方便。當然,要使redux-logger生效,需要保證在系統中使用redux進行狀態管理,否則沒有任何日志輸出。
Redux-logger的使用方法可以分為兩種,基本使用方法如下:
import { applyMiddleware, createStore} from ‘redux'; import logger from ‘reudx-logger' const store = createStore( Reducer, applyMiddleware(logger) )
也可以自己寫一個日志輸出中間件,代碼如下:
var logger = store => next => action => { console.log('[action]', action) console.log(`[action] type:${action.type} payload:${JSON.stringify(action.payload)}`) next(action) console.log('[store]', store.getState()) console.log(`[store] ${JSON.stringify(store.getState())}`) }
上述就是小編為大家分享的如何使用Redux中間件了,如果剛好有類似的疑惑,不妨參照上述分析進行理解。如果想知道更多相關知識,歡迎關注億速云行業資訊頻道。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。