观察者模式和发布订阅模式

文章目录

观察者模式

Subject 和 Observer 直接绑定,中间无媒介。如点击事件,事件直接和按钮进行绑定。

发布订阅模式

Publisher 和 Observer 相互不认识,中间有媒介。如在 A 组件中绑定一个事件,在 B 组件中触发这个事件,这个两个组件相隔十万八千里互补认识,那么就通过中间event这个媒介来通讯。

发布订阅模式需要在代码中触发 emit ,而观察者模式没有 emit

手写观察者模式

jsx 复制代码
import React, { useState, useEffect } from 'react';

// 观察者函数
const observer = (newValue) => {
  console.log(`Subject changed to ${newValue}`);
};
const SubjectComponent = () => {
  // 使用useState创建一个状态变量
  const [subject, setSubject] = useState('Initial Value');
  // 使用useEffect来模拟观察者模式
  useEffect(() => {
    // 当subject变化时,调用观察者函数
    observer(subject); 
  }, [subject]); // 依赖数组中包含subject,这样每当subject变化时,useEffect都会执行
  // 更新subject的方法
  const updateSubject = () => {
    setSubject('Updated Value');
  };
  return (
    <div>
      <p>Subject: {subject}</p>
      <button onClick={updateSubject}>Update Subject</button>
    </div>
  );
};

export default SubjectComponent;

手写发布订阅模式

jsx 复制代码
// EventBus.js
import { createContext, useContext, useState } from 'react';

const EventBusContext = createContext();

export const EventBusProvider = ({ children }) => {
  const [events, setEvents] = useState({});

  const subscribe = (eventName, callback) => {
    if (!events[eventName]) {
      setEvents((prevEvents) => ({
        ...prevEvents,
        [eventName]: [],
      }));
    }
    setEvents((prevEvents) => ({
      ...prevEvents,
      [eventName]: [...prevEvents[eventName], callback],
    }));
  };

  const publish = (eventName, data) => {
    if (events[eventName]) {
      events[eventName].forEach((callback) => callback(data));
    }
  };

  return (
    <EventBusContext.Provider value={{ subscribe, publish }}>
      {children}
    </EventBusContext.Provider>
  );
};

export const useEventBus = () => useContext(EventBusContext);
相关推荐
我不吃饼干7 小时前
在 React 中实现倒计时功能会有什么坑
前端·react.js
haaaaaaarry9 小时前
Element Plus常见基础组件(二)
开发语言·前端·javascript
PyHaVolask9 小时前
HTML 表单进阶:用户体验优化与实战应用
前端·javascript·html·用户体验
花菜会噎住11 小时前
Vue3核心语法进阶(computed与监听)
前端·javascript·vue.js
I'mxx11 小时前
【vue(2)插槽】
javascript·vue.js
花菜会噎住11 小时前
Vue3核心语法基础
前端·javascript·vue.js·前端框架
全宝11 小时前
echarts5实现地图过渡动画
前端·javascript·echarts
啃火龙果的兔子12 小时前
解决 Node.js 托管 React 静态资源的跨域问题
前端·react.js·前端框架
sophie旭13 小时前
《深入浅出react》总结之 10.7 scheduler 异步调度原理
前端·react.js·源码
吃饭睡觉打豆豆嘛13 小时前
彻底搞懂前端路由:从 Hash 到 History 的演进与实践
前端·javascript