redux8 - redux 中间件 和 applyMiddleware 及其实现原理

参考redux仓库, redux-logger库
所有1-8系列代码仓库

  • 新建个项目吧 - 引入 redux, react-redux

中间件执行流程图


在这里插入图片描述


演示代码仓库
在这里插入图片描述
就这个演示了,点击 + 1 ,现在呢, 我想打印个日志,就是每次点击按钮,都能打印出老的状态和新的状态

  • 理逻辑,既然是在每次点击事件之后打印,那么,如果想拿到老的状态,就需要在派发前,想拿到新的状态,就是在派发后
    先这样写:
let store = createStore(reducers);
let dispatch = store.dispatch;
store.dispatch = function(action) {
  console.log(`老值: ${JSON.stringify(store.getState())}`);
  dispatch(action);
  console.log(`新值:${JSON.stringify(store.getState())}`);
};
export default store

这样一来已经实现了,那上边的代码,核心就是重写 了reduxdispatch方法,

  1. 先存起来一份老的, 用于用户的派发action
  2. 再重写一份 dispatch 方法, 用于,在派发前和派发后做某些事
  • 接着整个异步逻辑,点击延时1秒再加1, 接着重写 dispatch, 1秒后,再派发action
store.dispatch = function(action) {
  setTimeout(() => {
    dispatch(action);
  }, 1000);
};

参考logger的实现第67行开始, 可以看到 连续返回了3个函数, 同时,第一个参数拿到getState, 第二个参数传入老的 dispatch, 第三个参数就是reducer,接着实现一个简化版logger中间件
在这里插入图片描述

function logger({ getState }) {
  return function(next) {
    return function(action) {
      console.log(`老值: ${JSON.stringify(getState())}`);
      next(action);
      console.log(`新值: ${JSON.stringify(getState())}`);
    };
  };
}
let store = applyMiddleware(logger)(createStore)(reducers)

在这里插入图片描述
好了, 来接着推导 applyMiddleware 方法, 它接收的参数有 自己写的 logger 中间件, redux的 createStore方法, 还有自己的reducer, 它连续返回了3个函数, 代码实现就是下边这样的

// 传入自己的中间件
function applyMiddleware(middleWare) {
  // 传入 redux 的 createStore 方法
  return function(createStore) {
  	// 传入自己的reducer
    return function(reducer) {
     	let store = createStore(reducer);
     	// 包裹了一圈, 最后还是返回了 store因为外部要接收store对象
     	// 此时,还没有处理 中间件 middleWare 参数
      	return store;
    };
  };
}

处理 传入的 middleWare参数 (也就是中间件)
在这里插入图片描述

function applyMiddleware(middleWare) {
  // 传入 redux 的 createStore 方法
  return function(createStore) {
  	// 传入自己的reducer
    return function(reducer) {
     	let store = createStore(reducer);
     	// 处理middleWare 参数, 看着上边的 logger 函数写
     	// 1. 先执行第一次传入 store 实参, 供 logger 组件解构出 getState 参数
     	middleWare = middleWare(store)
     	// 再执行第二次 传入 dispatch 供 next 使用派发action
     	let dispatch = middleWare(store.dispatch)
     	// 将这个与 store的 dispatch 进行替换掉
      	return {
			...store,
			dispatch
		};
    };
  };
}

打印,实现了 单一中间件的处理,但实际开发中,中间件可能有多个的,下篇再接着聊
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值