Redux-Middleware 解析
以上是 Dan Abramov 对 middleware 的描述,他提供了一个分类处理 action 的机会,在 middleware 中,你可以检阅每一个流过的 action,挑选出特定类型的 action 进行相应操作,给你一次改变 action 的机会,
看一下使用方法:
1 2 3 4 5 6
| import { Middleware } from "react"; export const logger: Middleware = (store) => (next) => (action) => { console.log(action); return next(action); };
|
Middleware 具体是如何实现的呢
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| export default function applyMiddleware(...middlewares) { return (createStore) => (reducer, preloadedState, enhancer) => { var store = createStore(reducer, preloadedState, enhancer); var dispatch = store.dispatch; var chain = []; var middlewareAPI = { getState: store.getState, dispatch: (action) => dispatch(action), }; chain = middlewares.map((middleware) => middleware(middlewareAPI)); dispatch = compose(...chain)(store.dispatch); return { ...store, dispatch, }; }; }
|
了解一下 compose 函数:
1
| let result = compose(f1, f2, f3, f4)(value) -> let result = f1(f2(f3(f4(value))))
|
其中
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| chain = middlewares.map(middleware => middleware(middlewareAPI)) dispatch = compose(...chain)(store.dispatch)
fnMiddle = fn(middlewareAPI) dispatch = fnMiddle(store.dispatch)
dispatch = fn(middlewareAPI)(store.dispatch)
store.dispatch(action)
fn(middlewareAPI)(store.dispatch)(action)
dispatch = compose(...chain)(store.dispatch) === dispatch = fn1Middle(fn2Middle(store.dispatch))
(action) => { ... next(action) ... }
|
以上的图示表明,redux 的 middleware 是多层函数包裹结构,每个 middleware 执行完之后,就会将结果返回给下一个 middleware,其中 return 的函数参数为 action,函数体会执行 next(action),而 next 正是第一次传入 store.dispatch,因为这里是用了 compose 编程思想,将不变的函数参数以科里化的形式作为参数传入,如 store,next,而变化的参数如 action 则作为最后一个参数传入,形如:
1 2
| middleware = (store) => (next) => (action) => {};
|