中间件原理 手动封装中间件
在redux添加自己的操作,完成打印日志需求
- 需求:在dispatch之前,打印一下本次的action对象,dispatch完成之后,可以打印最新的store state
console.log("dispatching:", addAction(5));
store.dispatch(addAction());
console.log("new state:", store.getState());
console.log("dispatching:", addAction(10));
store.dispatch(addAction());
console.log("new state:", store.getState());
这种方式缺陷很明显:
- 首先,每一次进行dispatch的操作时,都得加上这种逻辑代码
- 其次,存在大量的重复的代码,代码显得很臃肿
有没有更优雅的方式,用来处理这种逻辑呢?
- 可以把上边的逻辑封装成一个函数
function dispatchAndLog(action) {
console.log("dispatching:", action());
store.dispatch(action);
console.log("new state:", store.getState());
}
dispatchAndLog(addAction(10));
但是这样的方式有一个非常大的缺陷:
- 每次想要dispatch的时候,就必须使用封装的函数dispatchAndLog;
- 显然,对于使用者来说,很难记住这样的API,更加习惯直接调用dispatch
我们可以对代码进行进一步的优化;
修改dispatch
我们对代码进行如下的修改:
- 这样就意味着,我们直接修改了dispatch的调用过程;
- 在调用dispatch的过程中,真正被调用的函数其实是我们手动封装的函数dispatchAndLog
let next = store.dispatch;
function dispatchAndLog(action) {
console.log("dispatching:", action());
next(action());
console.log("new state:", action());
}
store.dispatch = dispatchAndLog;
我们可以讲代码进一步完善,将它封装到一个模块当中;
function patchLogging(store) {
let next = store.dispatch;
function dispatchAndLog(action) {
console.log("dispatching:", action);
next(action);
console.log("new state:", store.getState());
}
store.dispatch = dispatchAndLog;
}