React项目中使用发布订阅模式

React项目中使用发布订阅模式

发布订阅模式(也称观察者模式)是一种管理跨组件通信的有效方式,尤其是在不希望直接依赖于特定组件的情况下。这种模式允许一个对象(发布者)通知多个其他对象(订阅者),而不必知道这些对象是谁或他们在哪里。这有助于解耦组件,使得代码更加模块化和可维护。

1.创建发布订阅器

创建一个发布订阅器类,负责管理时间的注册、取消和触发

javascript 复制代码
# js
class PubSub {
	constructor(){
		this.events = {}
	}
	subscribe(event, callback){
		if(!this.events[event]){
			this.events[event] = []
		}
		this.events[event].push(callback)
	}
	unsubscribe(event,callback){
		if(this.events[event]){
			this.events[event] = this.events[event].filter(
				cb => cb !== callback
			)
		}
	}
	publish(event,data){
		if(this.events[event]){
			this.events[event].forEach(callback => callback(data))
		}
	}
}

const pubsub = new PubSub()
typescript 复制代码
# ts

interface EventMap {
  [eventName: string]: any;
}

class EventCenter {
  private listeners = {}

  constructor(){
    this.listeners = {}
  }
  subscribe<T extends keyof EventMap>(event: T, callback: (data?: EventMap[T]) => void) {
    if(!this.listeners[event]) {
      this.listeners[event] = []
    }
    this.listeners[event].push(callback)
  }

  publish<T extends keyof EventMap>(event: T, data?: EventMap[T]) {
    const callbacks = this.listeners[event]
    if(callbacks) {
      callbacks.forEach(callback => {
        callback(data)
      })
    }
  }

  unsubscribe<T extends keyof EventMap>(event: T, callback?: (data: EventMap[T]) => void) {
    const callbacks = this.listeners[event];
    if (callbacks) {
        if (callback) {
            this.listeners[event] = callbacks.filter(cb => cb !== callback);
        } else {
            delete this.listeners[event];
        }
    }
  }
}

export default new EventCenter()

2.在组件中使用发布订阅器

在你的React组件中使用这个发布订阅器。例如,一个组件可以订阅事件以接收数据,而另一个组件可以发布事件来发送数据。假设你有一个按钮组件,当点击时,他会触发一个事件发送一些数据

javascript 复制代码
import React from 'react';
import { pubsub } from './pubsub'; // 引入上面定义的PubSub实例

class ButtonComponent extends React.Component {
  handleClick = () => {
    pubsub.publish('dataUpdated', { message: 'Hello World!' });
  };

  render() {
    return (
      <button onClick={this.handleClick}>
        Click me!
      </button>
    );
  }
}

3. 订阅数据

另一个组件可以订阅这个事件,并在接收到数据时执行某些操作

javascript 复制代码
import React, { useEffect, useState } from 'react';
import { pubsub } from './pubsub'; // 引入上面定义的PubSub实例

interface DisplayProps {}
interface DisplayState {
  message: string;
}

const DisplayComponent: React.FC<DisplayProps> = () => {
  const [message, setMessage] = useState('');

  useEffect(() => {
    const handleDataUpdate = ({ message }: { message: string }) => {
      setMessage(message);
    };

    pubsub.subscribe('dataUpdated', handleDataUpdate);

    return () => {
      pubsub.unsubscribe('dataUpdated', handleDataUpdate);
    };
  }, []);

  return <div>{message}</div>;
};

export default DisplayComponent;
相关推荐
xiao-xiang15 分钟前
jenkins-通过api获取所有job及最新build信息
前端·servlet·jenkins
C语言魔术师31 分钟前
【小游戏篇】三子棋游戏
前端·算法·游戏
匹马夕阳2 小时前
Vue 3中导航守卫(Navigation Guard)结合Axios实现token认证机制
前端·javascript·vue.js
你熬夜了吗?2 小时前
日历热力图,月度数据可视化图表(日活跃图、格子图)vue组件
前端·vue.js·信息可视化
screct_demo3 小时前
詳細講一下在RN(ReactNative)中,6個比較常用的組件以及詳細的用法
javascript·react native·react.js
桂月二二8 小时前
探索前端开发中的 Web Vitals —— 提升用户体验的关键技术
前端·ux
hunter2062069 小时前
ubuntu向一个pc主机通过web发送数据,pc端通过工具直接查看收到的数据
linux·前端·ubuntu
qzhqbb9 小时前
web服务器 网站部署的架构
服务器·前端·架构
刻刻帝的海角9 小时前
CSS 颜色
前端·css
九酒10 小时前
从UI稿到代码优化,看Trae AI 编辑器如何帮助开发者提效
前端·trae