Redux - 中介軟體



Redux 本身是同步的,那麼像網路請求這樣的非同步操作如何在 Redux 中工作?這裡中介軟體就派上用場了。如前所述,reducers 是編寫所有執行邏輯的地方。Reducer 與誰執行它、花費多少時間或記錄操作分派前後應用程式的狀態無關。

在這種情況下,Redux 中介軟體函式提供了一種在分派的操作到達 reducer 之前與其互動的方法。可以透過編寫高階函式(返回另一個函式的函式)來建立自定義中介軟體函式,該函式圍繞某些邏輯進行包裝。可以將多箇中間件組合在一起以新增新功能,並且每個中介軟體都不需要了解之前和之後發生了什麼。您可以將中介軟體想象成操作分派和 reducer 之間的東西。

通常,中介軟體用於處理應用程式中的非同步操作。Redux 提供了一個名為 applyMiddleware 的 API,它允許我們使用自定義中介軟體以及 Redux 中介軟體(如 redux-thunk 和 redux-promise)。它將中介軟體應用於 store。使用 applyMiddleware API 的語法如下:

applyMiddleware(...middleware)

這可以應用於 store,如下所示:

import { createStore, applyMiddleware } from 'redux';
import thunk from 'redux-thunk';
import rootReducer from './reducers/index';
const store = createStore(rootReducer, applyMiddleware(thunk));
Middleware

中介軟體將允許您編寫一個操作分派器,它返回一個函式而不是一個操作物件。下面顯示了相同內容的示例:

function getUser() {
   return function() {
      return axios.get('/get_user_details');
   };
}

可以在中介軟體內編寫條件分派。每個中介軟體都接收 store 的 dispatch,以便它們可以分派新的操作,並將 getState 函式作為引數,以便它們可以訪問當前狀態並返回一個函式。內部函式的任何返回值都將作為 dispatch 函式本身的值可用。

以下是中介軟體的語法:

({ getState, dispatch }) => next => action

getState 函式用於確定是否要獲取新資料或返回快取結果,具體取決於當前狀態。

讓我們來看一個自定義中介軟體日誌記錄函式的示例。它只是記錄操作和新狀態。

import { createStore, applyMiddleware } from 'redux'
import userLogin from './reducers'

function logger({ getState }) {
   return next => action => {
      console.log(‘action’, action);
      const returnVal = next(action);
      console.log('state when action is dispatched', getState()); 
      return returnVal;
   }
}

現在透過編寫以下程式碼行將日誌記錄中介軟體應用於 store:

const store = createStore(userLogin , initialState=[ ] , applyMiddleware(logger));

使用以下程式碼分派一個操作以檢查分派的操作和新狀態:

store.dispatch({
   type: 'ITEMS_REQUEST', 
	isLoading: true
})

下面是另一箇中間件示例,您可以在其中處理何時顯示或隱藏載入程式。此中介軟體在您請求任何資源時顯示載入程式,並在資源請求完成後隱藏它。

import isPromise from 'is-promise';

function loaderHandler({ dispatch }) {
   return next => action => {
      if (isPromise(action)) {
         dispatch({ type: 'SHOW_LOADER' });
         action
            .then(() => dispatch({ type: 'HIDE_LOADER' }))
            .catch(() => dispatch({ type: 'HIDE_LOADER' }));
      }
      return next(action);
   };
}
const store = createStore(
   userLogin , initialState = [ ] , 
   applyMiddleware(loaderHandler)
);
廣告

© . All rights reserved.