react事件订阅实现
React 事件订阅实现方式
在 React 中实现事件订阅通常涉及组件间通信或全局事件管理,以下是几种常见方法:
使用自定义事件(Pub/Sub 模式)
通过创建全局事件总线实现订阅发布模式:
// EventBus.js
const events = {};
export default {
subscribe(eventName, callback) {
if (!events[eventName]) {
events[eventName] = [];
}
events[eventName].push(callback);
},
publish(eventName, data) {
if (events[eventName]) {
events[eventName].forEach(callback => callback(data));
}
},
unsubscribe(eventName, callback) {
if (events[eventName]) {
events[eventName] = events[eventName].filter(cb => cb !== callback);
}
}
};
组件中使用:

import EventBus from './EventBus';
// 订阅
componentDidMount() {
EventBus.subscribe('dataUpdated', this.handleDataUpdate);
}
// 发布
EventBus.publish('dataUpdated', newData);
// 取消订阅
componentWillUnmount() {
EventBus.unsubscribe('dataUpdated', this.handleDataUpdate);
}
使用 Context API 实现跨组件通信
适合深层嵌套组件间的事件传递:
// EventContext.js
import React from 'react';
const EventContext = React.createContext({
subscribe: () => {},
publish: () => {}
});
export class EventProvider extends React.Component {
state = {
subscribers: {}
};
publish = (eventName, data) => {
const { subscribers } = this.state;
if (subscribers[eventName]) {
subscribers[eventName].forEach(callback => callback(data));
}
};
subscribe = (eventName, callback) => {
this.setState(prevState => ({
subscribers: {
...prevState.subscribers,
[eventName]: [...(prevState.subscribers[eventName] || []), callback]
}
}));
};
render() {
return (
<EventContext.Provider
value={{
publish: this.publish,
subscribe: this.subscribe
}}
>
{this.props.children}
</EventContext.Provider>
);
}
}
export const EventConsumer = EventContext.Consumer;
使用第三方库
如 eventemitter3 或 mitt 等轻量级事件库:

// 使用 mitt
import mitt from 'mitt';
const emitter = mitt();
// 订阅
emitter.on('event', data => console.log(data));
// 发布
emitter.emit('event', { foo: 'bar' });
// 取消订阅
emitter.off('event', handler);
使用 React Hooks 实现
适合函数组件的事件管理:
import { useEffect } from 'react';
function useEventSubscription(eventName, callback, dependencies = []) {
useEffect(() => {
// 模拟订阅
const eventHandler = (e) => callback(e.detail);
window.addEventListener(eventName, eventHandler);
return () => {
window.removeEventListener(eventName, eventHandler);
};
}, dependencies);
}
// 使用示例
function Component() {
useEventSubscription('customEvent', (data) => {
console.log('Received:', data);
}, []);
return <div>Event Listener</div>;
}
原生 DOM 事件订阅
对于需要监听 DOM 事件的场景:
class EventComponent extends React.Component {
handleClick = (e) => {
console.log('Clicked', e.target);
};
componentDidMount() {
document.addEventListener('click', this.handleClick);
}
componentWillUnmount() {
document.removeEventListener('click', this.handleClick);
}
render() {
return <div>Click anywhere</div>;
}
}
注意事项
- 组件卸载时务必取消订阅,避免内存泄漏
- 对于全局事件总线,注意命名冲突问题
- Context API 方案更适合 React 应用内部通信
- 第三方库通常提供更完善的功能和性能优化
- 函数组件优先考虑使用自定义 Hook 实现
选择哪种方式取决于具体场景:
- 简单父子组件通信:直接使用 props 传递回调
- 跨层级组件:Context API 或事件总线
- 全局事件:专用事件库或状态管理工具(如 Redux)






