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)
);
广告