let us say say Redux和它的中间件机制

Redux

首先一张图看看Redux基本内容:

react-redux

还是一张图看看如何在React中使用Redux:

中间件

这就不是一张图可以解释的了。

什么是中间件

允许开发者在派发一个action到他最终被reducer处理之前,对action进行一些额外的处理。

主要是增强store.dispatch的能力。

如何自定义中间件

重写dispatch方法

类似于VUE中数组实现响应式的原理:

js 复制代码
import { combineReducers,createStore } from 'redux';
import countReducer from "./reducers/count";
import userReducer from "./reducers/user";

const rootReducer = combineReducers({
  count:countReducer,
  user:userReducer
});

const store = createStore(rootReducer);

// 通过重写dispatch实现响应式
const originDispatch= store.dispatch; //缓存原始dispatch
store.dispatch = function(action){
  // 执行中间操作
  console.log('中间件获取action',action);
  console.log('中间件获取state',store.getState());
  originDispatch(action); //调用原始dispatch
};

export default store;

官方推荐方法

自定义 Redux 中间件通常涉及编写一个函数,该函数接收 store 对象的 dispatchgetState 方法,并返回一个函数,该函数再次接收 nextaction,允许你在 action 到达 reducer 之前或之后执行一些逻辑。

js 复制代码
const loggerStateMiddleware = store => next => action => {
  console.log('自定义middleWare2-logger-state', store.getState());
  return next(action);
};

export default loggerStateMiddleware;


const store = createStore(rootReducer,applyMiddleware(loggerStateMiddleware));

中间件的原理

首先从使用中间件的语法入手:

js 复制代码
const store = createStore(
  rootReducer,
  applyMiddleware(middleware1, middleware2)
);

那么接下来看看createStore做了什么呢?简化版createStore如下:

js 复制代码
function createStore(reducer, preloadedState, enhancer) {

/**createStore接收三个参数
 * 第一个参数是 rootReducer,用于处理状态变化,
 * 第二个参数是可选的初始状态(preloadedState),
 * 第三个参数是中间件链enhancer。
 */
 
  // 如果传入了 enhancer,则使用 enhancer 增强 createStore
  if (typeof enhancer === 'function') {
    return enhancer(createStore)(reducer, preloadedState);
  }

  // 内部状态
  let currentState = preloadedState;
  let currentReducer = reducer;
  let listeners = [];

  // 获取当前状态
  function getState() {
    return currentState;
  }

  // 触发 action,并更新状态
  function dispatch(action) {
    currentState = currentReducer(currentState, action);

    // 通知所有监听器(订阅者)
    listeners.forEach(listener => listener());

    return action;
  }

  // 订阅状态变化
  function subscribe(listener) {
    listeners.push(listener);

    // 返回一个取消订阅的函数
    return function unsubscribe() {
      listeners = listeners.filter(l => l !== listener);
    };
  }

  // 初始化 store
  dispatch({ type: '@@redux/INIT' });

  // 返回 store 对象
  return {
    getState,
    dispatch,
    subscribe,
  };
}

知道了createStore的基本处理,接下来看看applyMiddleware做了什么:

由下可以看出:

  • applyMiddleware内部也重写了dispatch
js 复制代码
function applyMiddleware(...middlewares) {
  // 返回一个高阶函数,接收 createStore 作为参数
  return createStore => reducer => {
    // 创建原始的 Redux store
    const store = createStore(reducer);
    
    // 初始化 dispatch 函数,指向原始的 store.dispatch
    let dispatch = store.dispatch;

    // middlewareAPI 包含 getState 和 dispatch 方法
    const middlewareAPI = {
      getState: store.getState,
      dispatch: action => dispatch(action)
    };

    // 将每个中间件传入 middlewareAPI,得到包装后的中间件函数
    const chain = middlewares.map(middleware => middleware(middlewareAPI));

    // compose 函数用于将多个函数从右到左组合起来
    dispatch = compose(...chain)(store.dispatch);

    // 返回一个增强版的 store,其中的 dispatch 已经被中间件包装
    return {
      ...store,
      dispatch
    };
  };
}

// compose 函数用于将多个函数组合成一个函数
function compose(...funcs) {
  return arg => funcs.reduceRight((composed, f) => f(composed), arg);
}

接下来一张图就能说清整体的流程了:

相关推荐
大圣编程12 分钟前
Python中continue语句的用法是什么?
开发语言·前端·python
yuhaiqiang13 分钟前
随手 vibecoding 的浏览器插件已经 6000 多次下载,聊聊他的产品设计
前端·后端·面试
之歆1 小时前
Vue商品详情与放大镜组件
前端·javascript·vue.js
再吃一根胡萝卜2 小时前
如何把小米 MiMo 接入 CodeBuddy,打造私有 Agent
前端
负责的蛋挞3 小时前
异步HttpModule的实现方式
java·服务器·前端
YFF菲菲兔4 小时前
其他 Hooks 解析
react.js
丹宇码农5 小时前
把 HLS 字幕玩出花:zwPlayer 如何让 M3U8 视频支持全文搜索、翻译与码率自适应
前端·javascript·音视频·hls·视频播放器
2501_943782355 小时前
【共创季稿事节】猜数字游戏:二分法思维与交互式反馈
前端·游戏·microsoft·harmonyos·鸿蒙·鸿蒙系统
GV191rLvq6 小时前
基于Socket实现的最简单的Web服务器【ASP.NET原理分析】
服务器·前端·asp.net