前言
redux compose 用于 applyMiddleware
/ createStore enhancer
, 理解 compose 原理对于理解 redux 很有必要.
Src
https://github.com/reactjs/redux/blob/v3.7.2/src/compose.js
1 | export default function compose(...funcs) { |
Example - middleware
拿 redux 自己的 middleware 举例
1 | const store = createStore(reducer, preloadedState, enhancer); |
- 一个 middleware 原型为
store => next => action => { ... }
- chain = middleware.map 这里, 传了
store = middlewareAPI
, 成员原型为next => action => {...}
dispatch = compose(...chain)(store.dispatch)
compose(...chain)
1 | // 假设 chain.length = 3 |
执行 compose(...chain)(store.dispatch)
因 middleware 中 action => {…}
部分和 store.dispatch 原型一致, 称为一个 middleware 的 dispatch 部分
- chain[2] 即最后一个 item, next 参数 =
store.dispatch
, 返回一个action => {...}
, 称为 chain[2] 的 dispatch 部分 - chain[1] 倒数第二个 item, next 参数 = chain[2] dispatch 部分, 返回
action => {...}
, 成为 chain[1] 的 dispatch 部分 - chain[0] 第一个 item, next 参数 = chain[1] dispatch 部分, 返回
action => {...}
, 称为 chain[0] 的 dispatch 部分
最后 compose(...chain)(store.dispatch)
- 结果是被 compose 的 chain[0] 的 dispatch 部分
- 每一个 middleware 中的 next 是下一个 middleware 的 dispatch 部分
- 最后一个 middleware 的 next 是 redux store 的 dispatch
心得
如果有一堆有相同目的的方法需要执行, 可以使用 redux compose 将其串起来, 对外暴露一个唯一入口
例如 [fn1, fn2, fn…] 有相同的原型, 需要串起来, 可以这样做
1 | fn = compose(...[ |
实战
例如 vue-router hook 中, 如 beforeEach, 如果要很多不想关的事情要做, 可以这样做
1 | const thing1 = composeNext => (to, from, next) => { |