React第十二节组件之间通讯之发布订阅模式(使用pubsub-js插件)

组件之间通讯常用方案
1、通过props
2、通过context
3、通过发布订阅模式
4、通过Redux 后面会有专栏介绍

1、安装 pubsub-js 插件 yarn add pubsub-js

常用的事件

a、发布事件 :传入一个自定义事件名称(name),以及要发布的消息内容(messagePubsub.publish('name', 'message')

还可以进行异步发布 Pubsub.publishSync('name', 'message')

b、订阅事件 :传入发布事件的的名称 (name),以及接收name事件传递参数的回调函数 callback,最终会返回一个类似setTimeout 的timer 用于标记当前订阅的事件,在取消订阅时候可以之间传入此值 let sub0 = Pubsub.subscribe('name', callback)

c、取消订阅
Pubsub.unsubscribe('name') // 可以传入发布事件名称进行取消
Pubsub.unsubscribe(sub0) // 还可以传入 订阅事件返回的标识进行取消

2、在发布事件组件中引入

相对于自定义的发布订阅器要简单一些

可以同时发布多个事件

javascript 复制代码
// 引入插件
import PubSub  from 'pubsub-js'
export default function ChildA() {
    const handlePublish = () => {
        // 调用发布事件
        PubSub.publish('onChangeName', '修改名称')
    }
  return (
    <div style={{background:'blue'}}>
      <h3>组件A</h3>
      <button onClick={handlePublish}>发布</button>
    </div>
  )
}

3、在订阅组件中使用

可以订阅多个事件,取消多个事件

javascript 复制代码
import { useEffect, useState } from "react"
import PubSub from "pubsub-js"
export default function ChildB() {
    const [name, setName] = useState('')
    const handleEvents = (fncName, data) => {
        /***
         * @description 回调函数接收两个参数
         * @param {String} fncName 发布的函数名称,例如:onChangeName
         * @param {any} data 发布传递的数据消息
         * */ 
        console.log('=msg==', fncName, data)
        // 通过 useState 的set 函数进行视图更新
        setName(data)
    }
    useEffect(() => {
        // 订阅事件
        let token1 = PubSub.subscribe('onChangeName',handleEvents)
        return () => {
            PubSub.unsubscribe('onChangeName')  // 卸载时解除订阅
            // 两种卸载时候取消订阅方案
            // PubSub.unsubscribe('token1')  // 卸载时解除订阅
        }
    }, [])

  return (
    <div>
      <h3>组件B</h3>
      <p>组件A传递消息: {name}</p>
    </div>
  )
}

4、在父组件中使用

javascript 复制代码
import ChildA from './childA'
import ChildB from './childB'
export default function MyPubsub() {
  return (
    <div style={{background: 'red', padding: '12px', width: '360px', height: '500px'}}>
        <h2>父组件</h2>
        <ChildA></ChildA>
        <hr />
        {/* 完全独立的两个子组件 */}
        <ChildB></ChildB>  
    </div>
  )
}

注意:

a、不管是自定义发布订阅器,还是直接使用插件,在组件卸载时候,都有将当前组件的订阅取消,避免过多订阅运行,导致内存溢出

b、使用插件,相对更加方便简洁,只需要关注及时调用 api既可以,不需要注意发布订阅器里面的逻辑

c、要避免多状态,多个发布订阅器存在多组件中,会在出现bug时候造成难以追踪定位问题点;

相关推荐
晓13131 分钟前
前端篇——番外篇 Bootstrap框架
前端·javascript·css·html
黑心的奥利奥2 分钟前
前端项目利用Gitlab CI/CD流水线自动化打包、部署云服务
前端·ci/cd·gitlab
墨菲安全7 分钟前
NPM组件 @ivy-shared-components/iconslibrary 等窃取主机敏感信息
前端·npm·node.js·npm组件投毒·主机敏感信息窃取·恶意npm包
盛夏绽放42 分钟前
Excel导出实战:从入门到精通 - 构建专业级数据报表的完整指南
开发语言·javascript·excel·有问必答
Mintopia44 分钟前
🌀曲面细分求交:在无限细节中捕捉交点的浪漫
前端·javascript·计算机图形学
Mintopia1 小时前
🧙‍♂️用 Three.js 判断一个点是否在圆内 —— 一次圆心和点的对话
前端·javascript·three.js
liliangcsdn1 小时前
mac mlx大模型框架的安装和使用
java·前端·人工智能·python·macos
CssHero1 小时前
基于vue3完成领域模型架构建设
前端
PanZonghui1 小时前
用项目说话:我的React博客构建成果与经验复盘
前端·react.js·typescript
挽淚1 小时前
JavaScript 数组详解:从入门到精通
javascript