Redux中间件中ES6链式箭头函数含义咨询
首先帮你修正代码里的小笔误(不然运行会报错),正确的日志中间件代码如下:
const loggerMiddleware = store => next => action => { console.log('currentState', store.getState()); console.log('action', action); const result = next(action); console.log('nextState', store.getState()); console.log('\n'); return result; } export default loggerMiddleware;
接下来咱们一步步拆解这个连续箭头函数store => next => action => {}的含义:
这种写法其实是ES6函数柯里化的简洁表达,等价于三层嵌套的普通函数,而这正好是Redux中间件要求的标准结构,每层函数都有明确的作用:
第一层:
store => ...
Redux在加载中间件的阶段,会先调用这一层函数,并把Redux的核心store对象传进来。在这里你可以拿到store.getState()获取当前全局状态,也能调用store.dispatch()(不过中间件里一般用next传递action,避免触发循环调用)。第二层:
next => ...
这是Redux实现中间件串联的关键。next是一个函数,代表当前中间件之后的下一个中间件的处理函数。如果这个中间件是最后一个,那next就是Redux原生的dispatch函数。这一层调用发生在中间件初始化完成后、准备处理action之前。第三层:
action => ...
这才是每次调用store.dispatch(action)时真正执行的业务逻辑。当action被dispatch时,会依次经过每个中间件的这一层函数,你可以在这里实现各种自定义逻辑:- 先打印当前状态和要处理的action(对应代码里前两个
console.log) - 调用
next(action)把action传递给下一个中间件(或原生dispatch),让Redux处理action并更新状态 - 状态更新完成后,打印更新后的状态(第三个
console.log) - 返回
result——也就是next(action)的返回值,通常就是传入的action本身,这样上层的dispatch调用可以拿到这个返回值
- 先打印当前状态和要处理的action(对应代码里前两个
如果换成普通函数的写法,你会看得更直观,两者完全等价:
// 等价的普通函数写法 function loggerMiddleware(store) { return function(next) { return function(action) { console.log('currentState', store.getState()); console.log('action', action); const result = next(action); console.log('nextState', store.getState()); console.log('\n'); return result; } } }
这种三层嵌套结构,刚好实现了Redux中间件的「洋葱模型」:action先依次经过所有中间件的前置逻辑,到达reducer更新状态后,再依次经过中间件的后置逻辑,非常适合做日志、异步操作这类需要在action前后做处理的场景。
内容的提问来源于stack exchange,提问作者김기현

