上篇文章我们分析了createStore和combineReducers文件,这一篇我们分析剩下的文件。
首先是bindActionCreators文件,这个文件十分简单
function bindActionCreator(actionCreator, dispatch) {
return function() {
return dispatch(actionCreator.apply(this, arguments))
}
}
上面的高阶函数是在文件内部中使用,这个是为了减少重复代码,返回的函数中的参数传给的actionCreator函数执行,然后dispatch将其返回值作为参数再执行,其返回值作为该函数的返回值。
export default function bindActionCreators(actionCreators, dispatch) {
if (typeof actionCreators === 'function') {
return bindActionCreator(actionCreators, dispatch)
}
if (typeof actionCreators !== 'object' || actionCreators === null) {
throw new Error(
`bindActionCreators expected an object or a function, instead received ${
actionCreators === null ? 'null' : typeof actionCreators
}. ` +
`Did you write "import ActionCreators from" instead of "import * as ActionCreators from"?`
)
}
const keys = Object.keys(actionCreators)
const boundActionCreators = {}
for (let i = 0; i < keys.length; i++) {
const key = keys[i]
const actionCreator = actionCreators[key]
if (typeof actionCreator === 'function') {
boundActionCreators[key] = bindActionCreator(actionCreator, dispatch)
}
}
return boundActionCreators
}
这个函数很简单,其中第一个参数既可以是函数也可以是对象,如果是函数,则直接返回bindActionCreator处理后的函数,若为对象,则通过循环其key值递归找到每一个对应的ActionCreator,最后返回一个相应的对象。
也就是说,如果输入的是函数,则返回的是函数,若输入的是对象,则返回的也是对象。
接下来我们看compose文件(其实这个文件只是一个工具函数)
export default 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参数为空时,则返回一个函数,该函数直接返回其参数
若参数为一个时,则直接返回该参数(该参数应当是一个函数)
若参数为多个时,则通过reduce进行累计,返回一个函数,该函数内部是一层一层函数的叠加,该函数参数在叠加的最内层调用。举个栗子��
compose(f, g, h)就意味着
返回(...args) => f(g(h(...args)))
而compose函数在applyMiddleware中被使用
export default function applyMiddleware(...middlewares) {
return createStore => (...args) => {
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.`
)
}
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
}
}
}
该函数接收多个函数作为参数,然后返回一个函数,该函数又返回一个函数(说真的不喜欢这样的千层饼。。。),而这个函数则返回解散的store和dispatch
在最内层的函数立刻,首先通过createSotre创建了一个store,然后定义了一个奇葩版的dispatch,也就是说在使用中间件里严禁调用dispatch
然后通过map将state和奇葩版的dispatch传入中间件,最后通过compose将其dispatch作为千层饼最内层被中间件一层一层的裹起来,这样日后调用dispatch就必然会调用一层一层的中间件。(dispatch的结果作为参数),最后将这些值作为返回值
最后是我自己写的一个超简易版redux,功能不及正版redux强大,但胜在简单,有兴趣的朋友可以看一下
redux的内容在redux文件夹内,clone后npm install最后npm start即可