
React 发布订阅模式最佳实践:借助 mitt 实现组件解耦

前言
发布订阅(Pub/Sub)模式是一种常见的设计模式,用于解耦组件之间的通信。在 React 中,组件间通信通常通过 props 或 Context 实现,但当应用复杂时,使用事件总线(Event Bus)会更加灵活。mitt 是一个轻量级的事件库,非常适合实现发布订阅模式。
什么是 mitt?
mitt 是一个极简的事件发射器(event emitter),体积小(不到 200 字节),API 简单,支持 TypeScript。它允许你创建一个事件总线,组件之间通过事件名称发布和订阅消息。
为什么选择 mitt?
| 特点 | 说明 |
|---|---|
| 体积小 | 仅几百字节,适合前端轻量级事件管理 |
| 简单易用 | API 简洁,学习成本低 |
| 支持 TypeScript | 内置类型定义,开发体验好 |
| 灵活性高 | 适合跨组件、跨模块通信 |
安装 mitt
在你的 React 项目中,使用 npm 或 yarn 安装 mitt:
bashnpm install mitt # 或者 yarn add mitt
创建事件总线实例
通常我们会单独创建一个事件总线文件,供全局使用。
js// src/eventBus.js import mitt from 'mitt'; const emitter = mitt(); export default emitter;
在 React 中使用 mitt 实现发布订阅
1. 订阅事件
在需要监听事件的组件中,使用 emitter.on(eventName, handler) 订阅事件,并在组件卸载时取消订阅(防止内存泄漏)。
jsximport React, { useEffect, useState } from 'react'; import emitter from './eventBus'; function Subscriber() { const [message, setMessage] = useState(''); useEffect(() => { const handler = (data) => { setMessage(data); }; emitter.on('my-event', handler); // 组件卸载时取消订阅 return () => { emitter.off('my-event', handler); }; }, []); return <div>接收到的消息: {message}</div>; }
2. 发布事件
在需要发送事件的组件中,使用 emitter.emit(eventName, data) 发布事件。
jsximport React from 'react'; import emitter from './eventBus'; function Publisher() { const sendMessage = () => { emitter.emit('my-event', 'Hello from Publisher!'); }; return <button onClick={sendMessage}>发送消息</button>; }
完整示例代码
jsx// src/eventBus.js import mitt from 'mitt'; const emitter = mitt(); export default emitter;
jsx// src/Publisher.js import React from 'react'; import emitter from './eventBus'; function Publisher() { const sendMessage = () => { emitter.emit('my-event', 'Hello from Publisher!'); }; return <button onClick={sendMessage}>发送消息</button>; } export default Publisher;
jsx// src/Subscriber.js import React, { useEffect, useState } from 'react'; import emitter from './eventBus'; function Subscriber() { const [message, setMessage] = useState(''); useEffect(() => { const handler = (data) => { setMessage(data); }; emitter.on('my-event', handler); return () => { emitter.off('my-event', handler); }; }, []); return <div>接收到的消息: {message}</div>; } export default Subscriber;
jsx// src/App.js import React from 'react'; import Publisher from './Publisher'; import Subscriber from './Subscriber'; function App() { return ( <div> <h1>React + mitt 发布订阅示例</h1> <Publisher /> <Subscriber /> </div> ); } export default App;
总结
mitt是一个轻量、简单的事件库,适合 React 中实现发布订阅模式。- 通过创建全局事件总线,实现跨组件通信,避免复杂的 props 传递。
- 订阅时要注意在组件卸载时取消订阅,防止内存泄漏。
- 适用于中小型项目或特定场景下的事件通信。