发布订阅模式的应用:解决react中复杂层级的数据交互

以自定义事件为调度中心,创建一个EventCenter类,默认导出一个EventCenter实例

// 调度中心
class EventCenter {constructor() {// 创建一个事件中心,数据模型:{ event : [fn, fn] }this.eventCenter = {};}/*** 订阅事件* eventName {string} 订阅事件名称* backFn {Function} 收到通知的回调函数**/listen(eventName, backFn) {// 确定是否有订阅过该事件if (!this.eventCenter[eventName]) {this.eventCenter[eventName] = [];}// 控制backFn的唯一性,防止出现重复的backFnconst backFnList = this.eventCenter[eventName];const hasFn = backFnList.some((fn) => fn === backFn);if (hasFn) {return;}backFnList.push(backFn);}/*** 取消订阅函数* eventName {string} 取消订阅的事件名称* backFn {Function} 取消订阅的回调函数**/unListen(eventName, backFn) {// 判断是否有该事件,及该事件是否有订阅者let backFnList = this.eventCenter[eventName];if (!backFnList || backFnList.length === 0) {return;}backFnList = backFnList.filter((fn) => fn !== backFn); // 过滤掉取消订阅的函数}/*** 发布函数* eventName {string} 发布通知的事件名称* ...args {any} 发布通知的相关参数**/publish(eventName, ...args) {// 判断是否有该事件,及该事件是否有订阅者const backFnList = this.eventCenter[eventName];if (!backFnList || backFnList.length === 0) {return;}backFnList.forEach((backFn) => {backFn.apply(null, args); // 调用回调函数,并传入发布时的相关参数});}
}export default new EventCenter(); // 默认导出一个实例

publish中使用了apply是为了把参数进行转换,具体请参考此文章:《javascript 关于bind、apply、call函数改变this指向》

运用场景一: 添加商品与购物车的数量变化,这种情况往往是不知道跨越多少不同层级的情况。
发布者:商品加入购物车的操作
订阅者:购物车的数量

// 商品列表 ProductList.js
import EventCenter from './EventCenter';
const ProductList = ()=>{// 模拟商品数据const productList = [{id:1, name: '商品1'}];const addBuyCar = (product)=>{EventCenter.publish('addBuyCar', product); // 发布通知,添加商品到购物车}return (<ul>{productList.map(product => {return (<li key={product.id}>商品名称:{product.name} <button onClick={()=>addBuyCar(product)}>加入购物车</button></li>)})}</ul>);
}
export default ProductList;
// 购物车商品种类数量 BuyCarCount.js
import {useEffect, useState} from 'react';
import EventCenter from './EventCenter';
const BuyCarCount = ()=>{const [productList, setProductList] = useState([]); // 产品种类列表useEffect(()=>{// 订阅添加商品时的回调函数const backFn = (product)=>{setProductList(pList => {// 判断购物车是否已存在此商品,没有才添加进去const hasProduct = pList.some(pro => pro.id === product.id);if(!hasProduct){return [...pList, product];}return pList;});}EventCenter.listen('addBuyCar', backFn); // 订阅addBuyCar事件return ()=> EventCenter.unListen('addBuyCar', backFn); // 组件销毁后,取消订阅}, []);return <div>购物车商品种类:{productList.map(item=> item.name)}</div>;
}
export default BuyCarCount;

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/662061.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

151基于matlab的齿轮-轴-轴承系统的含间隙非线性动力学模型

基于matlab的齿轮-轴-轴承系统的含间隙非线性动力学模型&#xff0c;根据牛顿第二定律&#xff0c;建立齿轮系统啮合的非线性动力学方程&#xff0c;同时也主要应用修正Capone模型的滑动轴承无量纲化雷诺方程&#xff0c;利用这些方程推到公式建模&#xff1b;用MATLAB求解画出…

【Go】在 JSON 中解析 time.Duration

当解析 JSON 时&#xff0c;使用time.Duration可能是一个繁琐的过程&#xff0c;因为它需要在一秒的后面添加 9 个零&#xff08;即 1000000000&#xff09;。为了简化这个过程&#xff0c;我创建了一个名为 Duration 的新类型&#xff1a; type Duration time.Duration为了将…

查看docker服务的IP地址

要查看Docker容器服务的IP地址&#xff0c;可以使用以下命令&#xff1a; 如果你知道容器名称或容器ID&#xff0c;直接通过容器ID或容器名称来获取IP地址&#xff1a; # 使用容器ID获取IP地址 docker inspect -f {{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}} …

jupyter notebook显示的扩展很少,只有四五个--解决方案

如下&#xff1a;安装好只有四五个扩展 可以先删除 conda remove jupyter_nbextensions_configurator 然后使用pip安装 pip install jupyter_contrib_nbextensions jupyter contrib nbextensions install --user pip install jupyter_nbextensions_configurator jupyter nbex…

c++学习第十四讲---STL常用容器---vector容器

vector容器&#xff1a; 1.vector基本概念&#xff1a; vector功能与数组类似&#xff0c;与数组不同的是&#xff0c;vector可以动态扩展。 2.vector构造函数&#xff1a; vector<T> v; //默认构造函数&#xff0c;创建数据类型T的容器 ve…

在linux操作系统上编译并运行wpa_supplicant

前提&#xff1a;安装ubuntu虚拟机 本文使用的linux发行版本&#xff1a;Ubuntu 20.04.6 LTS 1 编译wpa_supplicant软件 1.1 下载wpa_supplicant wpa_supplicant各版本下载页面&#xff1a;Index of /releases 在页面中&#xff0c;不同前缀开头的表示不同的程序&#xff…

JAVA操作Rabbitmq-原理讲的很详细

这篇文章来源于稀土掘金&#xff0c;来源&#xff1a;https://juejin.cn/post/7132268340541653005&#xff0c;主要用来收藏学习。 常见的消息队列很多&#xff0c;主要包括 RabbitMQ、Kafka、RocketMQ 和 ActiveMQ&#xff0c;相关的选型可以看我之前的系列&#xff0c;这篇文…

Quick BI中lod函数之lod_fixed

一、lod函数简介 LOD函数的全称是详细级别表达式&#xff08;Level Of Detail Expressisons&#xff09;。它主要是为了克服一些表达式之间计算颗粒度不一致的问题。比如&#xff0c;要计算第一季度各月销售收入占比&#xff0c;这里分子计算颗粒度为’月’&#xff0c;但是分…

Armv8-M的TrustZone技术之测试目标指令

为了允许软件确定内存位置的安全属性,使用了TT指令(Test Target)。 Test Target(TT)查询内存位置的安全状态和访问权限。 Test Target Unprivileged(TTT)查询内存位置的安全状态和访问权限,以进行对该位置的非特权访问。 Test Target Alternate Domain(TTA)和Test…

【Python】P1 Python3 简介

目录 什么是 PythonPython 历史Python 应用方向Python 缺点 什么是 Python Python 是一个具有编译性、解释性、高可读性、高度互动性和面向对象的高级脚本编程语言。 编译性&#xff1a;Python 是一种解释型语言&#xff0c;代码运行时由解释器逐行读取和执行&#xff0c;而非…

运维SRE-02 正则表达式、grep

1.特殊符号补充 1.1位置相关的特殊符号 . 当前目录 .. 当前目录的上级目录 ~ 当前用户家目录 / 根目录 cd - 返回上次所在目录1.2熟练掌握 # 注释符号,root命令提示符 | 管道符号.1.3了解其他特殊符号 $ 取值(取出变量的值),普通用户的提示符 ! % ^ & * (){} [] ; ? \…

深入解析与实践:基于VUE-cli的Element-UI应用指南

一、前言 ​ 本文介绍 Element-UI快速入门&#xff0c;基于vue-cli构建的基础项目。关于 vue-cli 构建项目的详细流程&#xff0c;可参考博文&#xff1a; 使用vue脚手架构建项目 二、简介 element-ui 是饿了么前端出品的基于 Vue.js的 后台组件库&#xff0c;方便程序员进行…

前端JavaScript篇之let、const、var的区别

目录 let、const、var的区别 let、const、var的区别 let、const和var是JavaScript中用于声明变量的关键字&#xff0c;它们之间有一些区别。 首先&#xff0c;var是在ES5中引入的关键字&#xff0c;而let和const是在ES6中引入的。在ES6之前&#xff0c;我们只能使用var来声明…

思腾合力邀您共赴CNCC 2023中国计算机大会

思腾合力作为行业领先的人工智能基础架构解决方案商&#xff0c;受邀参加本次盛会。在会上展出思腾AI算力服务器&#xff0c;诚挚邀请众多参会嘉宾莅临展位&#xff0c;共同探讨人工智能与智能算力的产业趋势&#xff0c;共话技术创新发展&#xff0c;交流优秀产品与解决方案。…

ruoyi-cloud 使用笔记

1.接口文档访问 (1)swagger http://{ip}:{port}/swagger-ui/index.html http://localhost:8080/swagger-ui/index.html (2)knife4j http://{ip}:{port}/doc.html http://localhost:8080/doc.html

【操作系统·考研】文件系统

1.概述 文件系统(File System)提供高效和便捷的磁盘访问&#xff0c;以便允许存储、定位、提取数据。 严格来说&#xff0c;VFS并不是一种实际的FS&#xff0c;它只存在于内存中&#xff0c;不存在与任何外存空间中。 VFS在系统启动时建立&#xff0c;在系统关闭时消亡。 2.结…

js新增的操作元素类名的方法

Element.classList是一个只读属性&#xff0c;返回一个元素 class 属性的动态 DOMTokenList 集合。这可以用于操作 class 集合。 尽管 classList 属性自身是只读的&#xff0c;但是你可以使用 add()、remove()、replace() 和 toggle() 方法修改其关联的 DOMTokenList。 兼容性…

大规模语言模型LLM介绍

大规模语言模型LLM 大规模语言模型 向量数据库和数据库向量支持。 LLM基础设施&#xff1a;编程语言 Python&#xff0c;Java&#xff0c;C &#xff0c;js&#xff0c;新秀语言Mojo。 Mojo 这个语言是具有python和C&#xff0c;各取所长。结合了python的易用性和C语言的可…

如何从 Android SD 卡恢复已删除的文件

作为 Android 用户&#xff0c;您可能会使用 SD 卡来扩展手机的存储容量&#xff0c;并存储照片、视频和其他类型的文件。但意外发生时&#xff0c;您可能会错误地删除其中一些文件&#xff0c;或者由于其他原因而丢失它们。在大多数情况下&#xff0c;您可以通过主动并遵循正确…

基于STM32的花卉大棚环境监测系统设计

标题&#xff1a;基于STM32的花卉大棚环境监测系统设计 摘要&#xff1a; 随着智能农业的发展&#xff0c;对于精细化管理的需求日益增长。本文旨在设计一种基于STM32微控制器的花卉大棚环境监测系统&#xff0c;实现对温度、湿度、光照等关键参数的实时监控与调节&#xff0c…