applyMiddleware 的使用和原理
使用 applyMiddleware 的两种方式,其中 todos
是容器, ['Use Redux']
是参数, logger
是中间件
- 写法 1
const store = createStore(todos, ['Use Redux'], applyMiddleware(logger))
- 写法 2
const store =applyMiddleware(logger))(todos)(['Use Redux')
在 createStore
中参数 enhancer
表示中间件,也就是第三个参数。
// createStore 源码 function createStore(reducer, preloadedState, enhancer) { // 省略部分代码 return enhancer(createStore)(reducer, preloadedState) }
中间件的原理,applyMiddleware 是执行了三次,说明结构是这样的,返回两次函数
function applyMiddleware () { return function () { return function () { console.log('执行成功') } } } applyMiddleware()()()
继续深入其原理,需要了解中间件是怎么写的,中间件大概是这样的
function logger({ getState }) { return next => action => { console.log('将要提交动作', action) const returnValue = next(action) console.log('提交动作之后的状态', getState()) return returnValue } }
中间件返回两次函数,上面 logger
传入参数是代表下面的 middlewareAPI
对象,有 getState
和 dispatch
,和 store 不一样的。
export default function applyMiddleware(...middlewares) { return (createStore) => (reducer, preloadedState, enhancer) => { const store = createStore(reducer, preloadedState, enhancer) let dispatch = store.dispatch let chain = [] const middlewareAPI = { getState: store.getState, dispatch: (...args) => dispatch(...args) } // 中间件在这里第一次被调用 chain = middlewares.map(middleware => middleware(middlewareAPI)) dispatch = compose(...chain)(store.dispatch) return { ...store, dispatch } } } function compose(...funcs) { if (funcs.length === 0) { return arg => arg } if (funcs.length === 1) { return funcs[0] } return funcs.reduce((a, b) => (...args) => a(b(...args))) }
compose 方法接收所有执行过一次的中间件,虽然执行过一次,但还是函数返回函数的形式,代码 compose(...chain)(store.dispatch)
需要执行两次,注意这里不是三次
// 经过第 1 次处理 // middleware(middlewareAPI) function applyMiddleware (middlewareAPI) { console.log('第一次') return function () { console.log('第二次') return function () { console.log('第三层') } } } // 经过第 2 次处理 // compose() function () { console.log('第二次') return function () { console.log('第三层') } } // 经过第 3 次处理 // compose()() function (store.dispatch) { console.log('第三层') }
最后 dispatch 赋值的是新的函数,在第二步处理的时候,使用的是 reduce 参数的规则
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
上一篇: 合并乱序区间
下一篇: 不要相信一个熬夜的人说的每一句话
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论