Redux Middleware 是什么
当我们使用 Redux 时,我们知道 Reducer 是实现数据流的核心。然而,在实践中,我们难免需要额外的功能,例如日志记录、错误处理、异步操作等等,Redux Middleware 就是为了实现这些额外功能而被引入的中间件。
Redux Middleware 是一些函数,它们可以在 action 发送到 reducer 之前或之后拦截它们,并且可以在拦截时进行一些额外的操作。Redux Middleware 包含一系列预定义的函数,也可以自定义函数以实现独特的功能。
Middleware 在 Redux 架构中的角色
Middleware 在 Redux 架构中扮演一个非常特殊且重要的角色,每个 Middleware 连接着 action、reducer 和 state,并处理这些元素主要的数据流。
在 Redux 中,所有的 action 都会经过每个 Middleware 依次处理,最后到达 reducer。在 action 到达 reducer 的过程中,Middleware 可以修改 action、阻塞 action 或直接转发 action 及引起 side effect。因此,每个 Middleware 处理和传递 action 都是非常关键的,也是构建可扩展和可定制的 Redux 应用程序的关键之一。
在 Middleware 中,我们通常会用到 Redux 提供的 enhancer 函数 applyMiddleware()
,由 applyMiddleware()
返回的函数,可以使我们更方便地书写 Middleware,在应用程序的 store 上安装应用 Middleware。
import { applyMiddleware, createStore } from 'redux'; import thunk from 'redux-thunk'; import logger from 'redux-logger'; import rootReducer from './reducers'; const store = createStore( rootReducer, applyMiddleware(thunk, logger) );
如何自定义 Middleware
接下来,我们来手动实现一个简单的 Logger Middleware,以此来认识并深入理解 Middleware 的实现原理。
Logger Middleware 原理
Logger Middleware 实现日志记录的功能,例如记录每次 action 发送到 reducer 的状态信息、记录 action 发送和 reducer 响应的时间、记录 action 执行的结果等等。
为此,我们可以编写一个函数和 enhancer 函数来实现 Logger Middleware 的目标:
- 拦截接收到的 action,记录 payload、类型,以及时间戳;
- 将 action 和状态数据输出到控制台;
- 将新状态返回给下一个 Middleware,以便按照正常的数据流程进行操作。
Logger Middleware 代码实现
const loggerMiddleware = store => next => action => { const { type, payload } = action; const timestamp = new Date().toLocaleString(); console.log(`[${timestamp}] Action: ${type}, Payload: `, payload); const result = next(action); console.log(`[${timestamp}] Next State: `, store.getState()); return result; };
上面的代码实现了一个中间件,它用于记录 action 的类型、payload 和时间,同时输出新状态到控制台。
以上代码分为三部分:
const loggerMiddleware = ...
,定义函数loggerMiddleware
,并搭建了洋葱模型,接收 store、next 和 action,调用next(action)
时,实际上是将 action 传递给了下一个 Middleware。const {type, payload} = action; ...
,解构出 action 的类型和 payload,以及当前时间,输出日志。return result;
,返回 next(action) 的结果,使程序可以按正常逻辑继续执行。
Logger Middleware 安装和测试
需要注意习惯性的把自定义的 Middleware 安装到 store 中,使它可以拦截 state 的流动。
import {createStore, applyMiddleware} from 'redux'; import rootReducer from './reducers'; import loggerMiddleware from './middleware/loggerMiddleware'; const store = createStore(rootReducer, applyMiddleware(loggerMiddleware));
最后,我们用一个示例来测试 Logger Middleware:
const ADD_TODO = 'ADD_TODO'; const addTodo = (text) => ({ type: ADD_TODO, payload: {text} }); const rootReducer = (state = [], action) => { switch (action.type) { case ADD_TODO: return [...state, action.payload.text]; default: return state; } }; const store = createStore(rootReducer, applyMiddleware(loggerMiddleware)); store.dispatch(addTodo('Learn Redux')); // [2021-12-30 20:28:59] Action: ADD_TODO, Payload: {text: "Learn Redux"} // [2021-12-30 20:28:59] Next State: ["Learn Redux"]
在 console 中,我们看到了添加新 Todo 的时间、状态和内容。
总结
Redux Middleware 是实现数据流附加功能的关键组成部分,在实战中,我们常常通过应用 Middleware 来拦截和修改 action,进而实现日志记录、异步操作等功能。
我们了解了 Middleware 在 Redux 架构中的角色,并学习了如何自己创建 Middleware。还需要注意的是,我们需要把 Middleware 安装到 store 中,才能发挥 Middleware 的作用。
最后,我建议大家在实践中多动手,尝试自己编写一些有意思的 Middleware,并深入理解 Redux Middleware 在复杂应用程序中的各种使用方法。
来源:JavaScript中文网 ,转载请注明来源 本文地址:https://www.javascriptcn.com/post/65a28b50add4f0e0ffaa9f57