redux教程之源码解析3applyMiddleware(分析在注释中)

applyMiddleware是另一个核心函数
首先我们需要知道如何使用中间件
eg:
import { createStore, applyMiddleware } from 'redux'
import todos from './reducers'

function logger({ getState }) {
  return (next) => (action) => {
    console.log('will dispatch', action)

    // 调用 middleware 链中下一个 middleware 的 dispatch。
    let returnValue = next(action)

    console.log('state after dispatch', getState())

    // 一般会是 action 本身,除非
    // 后面的 middleware 修改了它。
    return returnValue
  }
}

let store = createStore(
  todos,
  [ 'Use Redux' ],
  applyMiddleware(logger)
)

store.dispatch({
  type: 'ADD_TODO',
  text: 'Understand the middleware'
})





 

中间件其实就是对reducer就行功能扩展,例如上面的例子,logger即在执行reducer时,输出正在执行的action名字
const a = [()=>{console.log(1)},()=>{console.log(2)},()=>{console.log(3)},()=>{console.log(4)}]
undefined
const b = a.reduce((a, b) => (...args) => a(b(...args)))
undefined
b(1)
VM8485:1 4
VM8485:1 3
VM8485:1 2
VM8485:1 1
undefined

 

源码
export default function applyMiddleware(...middlewares) {
  /**返回一个新的createStore函数 */
  return createStore => (...args) => {
    /**通过传入的reducer和action生成store */
    const store = createStore(...args)
    let dispatch = () => {
      throw new Error(
        `Dispatching while constructing your middleware is not allowed. ` +
          `Other middleware would not be applied to this dispatch.`
      )
    }
    /**对store和disptch改变成动态的,这样每次传入一个middleware的Store和disptch都是上一个middleware处理过的 */
    const middlewareAPI = {
      getState: store.getState,
      dispatch: (...args) => dispatch(...args)
    }
    const chain = middlewares.map(middleware => middleware(middlewareAPI))
    /**链式处理函数,即依次执行middleware数组中的各个中间件 */
    dispatch = compose(...chain)(store.dispatch)

    /**将所有中间件对reducer的扩展加入后,返回store和dispatch */
    return {
      ...store,
      dispatch
    }
  }
}

 

posted @ 2020-04-12 19:21  前端++  阅读(199)  评论(0编辑  收藏  举报