傻瓜教程:Redux 中间件

前言

Redux 是一种流行的状态管理工具,它被广泛应用于前端开发中。在 Redux 中,中间件是一种很重要的概念,它可以让 Redux 的功能更加强大和灵活。然而,许多前端开发者对中间件概念仍然存在困惑。本篇文章将第一时间去除你对 Redux 中间件的迷惑,帮助你更好地掌握这个概念。

Redux 中间件是什么?

Redux 中间件是 Redux 的基础之一,它可以拦截 Redux 的 action,对 action 进行处理后再传递给 reducer。中间件可以用于实现如下功能:

  • 记录日志
  • 审计数据
  • 异步处理数据
  • 控制 action 执行顺序
  • 等等……

这些功能的实现方法,都可以使用中间件来完成。

Redux 中间件的基本原理

Redux 中间件实现的核心功能就是拦截 action。中间件借助大量高阶函数的概念来实现,并通过 next 函数将控制权移交给下一个中间件。在 next 调用之前,中间件可以对 action 进行拦截、过滤以及修改等操作。

使用 Redux 中间件可以很方便地组合不同的中间件实现更强大的功能。Redux store 可以包含多个中间件,将多个中间件依次串联即可按顺序依次执行中间件操作。

Redux 中间件的基本用法

Redux 中间件的用法如下所示:

const middleware = store => next => action => {
  // 对 action 进行拦截和处理
  return next(action);
};

const store = createStore(reducer, applyMiddleware(middleware));

在上面的代码中,middleware 就是一个简单的中间件函数。它接收一个 store 参数,返回一个函数,这个函数又接收一个 next 参数,返回一个函数,最后一个函数接收一个 action 参数,最后再将 action 传递给 next 函数进行处理。

applyMiddleware 是一个函数工厂,它使用 Redux store 和中间件处理程序作为参数,返回一个包装 dispatch 的新函数。这个新函数可以拦截每个 action,并将它传递给中间件处理程序。

Redux 中间件的进阶应用

除了基本的用法,Redux 中间件还有一些进阶应用,例如控制中间件的执行顺序、使用异步中间件等。

控制中间件的执行顺序

Redux 中间件默认按顺序执行,也就是说,在一个中间件中调用了 next 函数,会依次将 action 传递给下一个中间件进行处理。但是有时我们希望能够控制中间件的执行顺序,Redux 中间件也提供了这个功能。

import { applyMiddleware, createStore } from "redux";

const middleware1 = store => next => action => {
  console.log("middleware1 before");
  next(action);
  console.log("middleware1 after");
};

const middleware2 = store => next => action => {
  console.log("middleware2 before");
  next(action);
  console.log("middleware2 after");
};

const store = createStore(
  reducer,
  applyMiddleware(middleware1, middleware2)
);

在上面的代码中,我们通过 applyMiddleware 方法将两个中间件依次添加到了 store 上。当 dispatch 一个 action 时,中间件的执行顺序如下:

使用异步中间件

在实际开发中,经常会出现异步调用的情况,此时需要使用异步中间件来实现,在 Redux 中,redux-thunkredux-saga 就是比较流行的异步中间件。

使用 redux-thunk 中间件

使用 redux-thunk 中间件可以方便地处理异步调用,我们来看一个示例代码:

const middleware = store => next => action => {
  if (typeof action === "function") {
    return action(store.dispatch, store.getState);
  }
  return next(action);
};

const fetchData = () => (dispatch, getState) => {
  dispatch({ type: "FETCH_START" });

  // 异步调用
  fetch("http://example.com/data")
    .then(res => res.json())
    .then(data => {
      dispatch({ type: "FETCH_SUCCESS", data });
    });
};

store.dispatch(fetchData());

在上面的代码中,我们定义了 middleware 中间件,它判断了 action 是否为函数。如果是函数,就将 store.dispatchstore.getState 作为参数传入 action 函数中执行,否则直接调用 next(action) 方法。

使用 redux-thunk 调用异步函数时,可以在 action 中返回一个函数。这个返回的函数接收两个参数 dispatchgetState,它们都是 Store 的方法。在异步调用成功后,可以再次调用 dispatch 方法触发一个 action。

使用 redux-saga 中间件

redux-saga 是一个基于 Generator 函数的异步中间件,它可以将异步调用转换成易于测试和阅读的代码。下面是一个简单的 redux-saga 示例:

import { put, takeLatest, call } from "redux-saga/effects";

function* fetchData() {
  try {
    yield put({ type: "FETCH_START" });

    const data = yield call(fetch, "http://example.com/data");
    const json = yield call([data, "json"]);

    yield put({ type: "FETCH_SUCCESS", data: json });
  } catch (error) {
    yield put({ type: "FETCH_ERROR", error });
  }
}

export default function* rootSaga() {
  yield takeLatest("FETCH_DATA", fetchData);
}

在上面的代码中,我们使用了 redux-saga 提供的几个关键字:

  • put: 发送一个 action 到 Store
  • call: 调用一个函数
  • takeLatest: 监听一个 action,当监听到多个 action 时,只处理最新的一个

通过使用 call 关键字,redux-saga 可以将异步调用变得可测试可读。使用 takeLatest 关键字可以防止多次触发该 action。

总结

本篇文章介绍了 Redux 中间件的基础和进阶用法,希望能对你对 Redux 中间件的理解和使用有所帮助。Redux 中间件是非常强大的工具,可以满足各种复杂需求,如何巧妙使用 Redux 中间件,将会使你的代码更加优雅和易维护。

来源:JavaScript中文网 ,转载请注明来源 本文地址:https://www.javascriptcn.com/post/65a3d1eaadd4f0e0ffbfc54a


纠错反馈