Redux - 中间件

Redux 本身是同步的,那么像网络请求这样的异步操作如何与Redux配合使用呢? 这里中间件就派上用场了。 如前所述,reducer 是编写所有执行逻辑的地方。 Reducer 与谁执行它、花费多少时间或在分派操作之前和之后记录应用程序的状态无关。

在这种情况下,Redux 中间件函数提供了一种媒介,在调度的操作到达reducer之前与它们进行交互。 可以通过编写高阶函数(返回另一个函数的函数)来创建定制的中间件函数,该函数包装了一些逻辑。 多个中间件可以组合在一起以添加新功能,并且每个中间件不需要了解之前和之后发生的事情。 您可以想象中间件位于分派的action和reducer之间。

通常,中间件用于处理应用程序中的异步操作。 Redux 提供了名为 applyMiddleware 的 API,它允许我们使用自定义中间件以及 Redux 中间件,例如 redux-thunk 和 redux-promise。 它应用中间件来存储。 使用 applyMiddleware API 的语法是 −

applyMiddleware(...middleware)

这可以应用于存储,如下所示 −

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

中间件将允许您编写一个操作调度程序,它返回一个函数而不是操作对象。 相同的示例如下所示 −

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

条件调度可以写在中间件内部。 每个中间件接收 store 的调度,以便它们可以调度新的操作,并且 getState 函数作为参数,以便它们可以访问当前状态并返回一个函数。 内部函数的任何返回值都可以用作调度函数本身的值。

以下是中间件的语法 −

({ 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)
);