溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

如何使用Redux中間件

發(fā)布時間:2021-06-16 15:21:54 來源:億速云 閱讀:112 作者:Leah 欄目:web開發(fā)

這期內(nèi)容當中小編將會給大家?guī)碛嘘P(guān)如何使用Redux中間件,文章內(nèi)容豐富且以專業(yè)的角度為大家分析和敘述,閱讀完這篇文章希望大家可以有所收獲。

為什么要使用中間件

在利用Redux進行狀態(tài)管理時,用戶在UI層面觸發(fā)行為,一個action對象通過store.dispatch派發(fā)到Reducer進行觸發(fā),接下來Reducer會根據(jù)type來更新對應(yīng)的Store上的狀態(tài)樹,更改后的state會觸發(fā)對應(yīng)組件的重新渲染。如下圖所示。在這個流程中,action對象是一個同步的對象,是一個包含type字段的簡單對象,但是在訪問服務(wù)器時,由于瀏覽器是單線程的,不會一遍渲染組件一遍等待服務(wù)器返回的結(jié)果,因此我們需要設(shè)計一種異步訪問服務(wù)器的方法來實現(xiàn)與服務(wù)器端的正常通信。

如何使用Redux中間件

中間件介紹

在Redux架構(gòu)下,一個action對象在通過store.dispatch派發(fā),在調(diào)用reducer函數(shù)前,會先經(jīng)過一個中間件環(huán)節(jié),如下圖所示。

如何使用Redux中間件

從上圖可以看出,在一個Redux架構(gòu)中可以用多個中間件,這些中間件一起組織處理請求的“管道”。一個中間件是一個獨立的函數(shù),可以組合使用,中間件有一個統(tǒng)一的接口,正因為一個中間件只能完成一個特定的功能,所以把多個中間件組合在一起才能滿足比較豐富的應(yīng)用需求。當然在使用時,也需要按照順序依次處理傳入的action,只有排在前面的中間件完成任務(wù)之后,后面的中間件才能有機會繼續(xù)處理action。

如何使用Redux中間件

中間件的特點

  • 中間件是獨立的函數(shù)

  • 中間件可以組合使用

  • 中間件有一個統(tǒng)一的接口

中間件接口

每個中間件必須定義為一個函數(shù),返回一個接受next參數(shù)的函數(shù),而這個接受next參數(shù)的函數(shù)又返回一個接受action參數(shù)的函數(shù)。next參數(shù)本身也是一個函數(shù),中間件調(diào)用這個next函數(shù)通知Redux自己的處理工作已經(jīng)結(jié)束。

一個什么都不做的中間件代碼如下:

function doNothingMiddleware({dispatch, getState}) {
  return function(next){
   return function(action){
    return next(action);
    }
  }
}

包含的功能有:

  • 調(diào)用dispatch派發(fā)出一個新的action對象

  • 調(diào)用getState獲得當前Redux Store上的狀態(tài)

  • 調(diào)用next告訴Redux當前中間件工作完畢,讓Redux調(diào)用下一個中間件

  • 訪問action對象action上的所有數(shù)據(jù)

在一個Redux應(yīng)用如果想要使用中間件,必須通過applyMiddleware來生成。Redux的源碼文件非常簡單,由五個文件一起組成,分別是createStore.js,applyMiddlware.js,compose.js,bindActionCreator.js,combineReducers.js。與createStore是用來創(chuàng)建一個狀態(tài)樹,并且暴露出幾個方法,包括dispatch,subscribe,getState,replaceReducer和$$observable,給createStore傳入的參數(shù)有reducer,preloadedState和enhancer,其中enhancer就是一個store增強器,是一個函數(shù),只能用applyMiddleware生成。applyMiddleware函數(shù)是根據(jù)外部函數(shù)(中間件函數(shù))包裝原來的dispatch函數(shù),然后將新的dispatch函數(shù)暴露出去。

//根據(jù)外部函數(shù)(中間件函數(shù))包裝原來的dispatch函數(shù),然后將新的dispatch函數(shù)暴露了出去
export default function applyMiddleware(...middlewares) {
 //return一個函數(shù),它可以接受createStore方法作為參數(shù),給返回的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.`
   )
  }

  //暴露兩個方法給外部函數(shù)
  const middlewareAPI = {
   getState: store.getState,
   dispatch: (...args) => dispatch(...args)
  }
  //傳入middlewareAPI參數(shù)并執(zhí)行每一個外部函數(shù),返回結(jié)果匯聚成數(shù)組
  const chain = middlewares.map(middleware => middleware(middlewareAPI))
  //這里用到了compose方法
  dispatch = compose(...chain)(store.dispatch)

  return {
   ...store,
   dispatch
  }
 }
}

中間件與增強器的區(qū)別

中間件和增強器都是對Redux Store的增強,但是中間件僅僅是對Redux Store的dispatch方法進行了增強,也就是從dispatch函數(shù)調(diào)用到action對象被reducer處理這個過程中的操作,增強器是對Redux Store進行更深層次的增強定制,需要使用Store Enhancer,通過閱讀增強器接口,一個增強器其實利用隨給的參數(shù)創(chuàng)造出一個store對象,然后定制對象,最后把Store對象返回。總的對比如下:

  • 中間件: 可以用來增強redux store的dispatch函數(shù),也就是從dispatch函數(shù)調(diào)用到action對象被reducer處理這個過程中的操作

  • 增強器: 對redux store進行更深層次的增強定制,可以增強redux store的各個方面。

異步訪問服務(wù)器:

異步action對象

在沒有引入中間件時,社會治理子系統(tǒng)在開發(fā)時,所有的action都是同步的,一個同步的action對象是一個包含type字段的簡單對象,但是我們需要實現(xiàn)一個異步action對象,是一個函數(shù),在action觸發(fā)之后,在reducer接收到執(zhí)行命令之前可以進行一個異步操作。

我們引入redux-thunk來實現(xiàn)異步訪問服務(wù)器方法,一個訪問服務(wù)器的action,至少要涉及三個action類型:

  • 表示異步操作已經(jīng)開始的action類型;

  • 表示異步操作成功的action類型;

  • 表示異步操作失敗的action類型;

Redux-thunk源代碼解析

Redux-thunk中間件是Redux中異步操作的解決方法之一,在action對象被reducer函數(shù)處理之前,是插入異步功能的時機,代碼非常簡單:

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函數(shù)返回了一個函數(shù),是實際處理每個action對象的函數(shù),首先檢查參數(shù)action的類型,如果是函數(shù)類型的話,就執(zhí)行這個action函數(shù),把dispatch和getState

作為參數(shù)傳遞出去,否則就調(diào)用next讓下一個中間件繼續(xù)處理action。

Redux-thunk的使用:

首先,安裝redux-thunk,在已經(jīng)安裝了node.js的命令窗口中運行 “npm install redux-thunk --save-dev”,在store.js中引入redux-thunk,并且確保redux的applyMiddleware函數(shù)也引入。具體實現(xiàn)代碼如下。

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后,我們也要設(shè)計異步操作的action對象,例如,在設(shè)備管理模塊中,成功保存設(shè)備信息后要重新獲取設(shè)備信息,代碼如下:

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返回的函數(shù)中,不僅可以dispatch一個同步的action對象,還可派發(fā)另一個異步action對象,來滿足一些有著先后關(guān)系的業(yè)務(wù)邏輯,代碼可讀性要比用Promise實現(xiàn)起來代碼更加清晰。

Redux-logger使用

在開發(fā)階段,我們需要對redux數(shù)據(jù)流中每個流程進行監(jiān)控,需要log輸出,redux-logger是官方推薦的一款日志中間件,使用起來非常方便。當然,要使redux-logger生效,需要保證在系統(tǒng)中使用redux進行狀態(tài)管理,否則沒有任何日志輸出。
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中間件了,如果剛好有類似的疑惑,不妨參照上述分析進行理解。如果想知道更多相關(guān)知識,歡迎關(guān)注億速云行業(yè)資訊頻道。

向AI問一下細節(jié)

免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI