React组件通信方式总结

文章目录

  • 父组件向子组件传递数据
  • 子组件向父组件传递数据
  • 兄弟组件传递数据
  • 祖先与后代组件之间的传值
  • 复杂关系的组件之间的传值
    • 使用发布-订阅模式
    • 使用 Redux

父组件向子组件传递数据

无论是类组件还是函数式组件,父组件向子组件传递数据的方式都是使用 props 来实现的

函数式组件:

// 父组件
import React from 'react';  
import ChildComponent from './ChildComponent';  
function ParentComponent() {  const message = 'Hello from Parent!';  return <ChildComponent message={message} />;  
}  
export default ParentComponent;  // 子组件(通过函数参数接收)
import React from 'react';  
function ChildComponent({ message }) {  return <div>{message}</div>;  
}  
export default ChildComponent;

类组件:

// 父组件
import React from 'react';  
import ChildComponent from './ChildComponent';  
class ParentComponent extends React.Component {  render() {  const message = 'Hello from Parent!';  return (  <div>  <ChildComponent message={message} />  </div>  );  }  
}  
export default ParentComponent;// 子组件(通过 `this.props` 接收)
import React from 'react';  
class ChildComponent extends React.Component {  render() {  const { message } = this.props;  return (  <div>{message}</div>  );  }  
}  
export default ChildComponent;

子组件向父组件传递数据

无论是类组件还是函数式组件,子组件向父组件传递数据的方式都是通过 回调函数 来实现的

  • 父组件自定义函数,用来接收数据,并将函数通过 props 传递给子组件
  • 子组件调用父组件传递的函数并传递数据

函数式组件:

// 父组件
import React from 'react';  
import ChildComponent from './ChildComponent';  
function ParentComponent() {  const handleDataFromChild = (data) => {  console.log('Received data from child:', data);  // 在这里处理从子组件接收到的数据  }  return (  <div>  <ChildComponent onDataReceived={handleDataFromChild} />  </div>  ); 
}  
export default ParentComponent;  // 子组件
import React from 'react';  
function ChildComponent({ onDataReceived }) {  const handleClick = () => {  const data = 'Hello from Child!';  onDataReceived(data); // 调用父组件传递的回调函数并传递数据  }  return (  <button onClick={handleClick}>Send Data to Parent</button>  );  
}  
export default ChildComponent;

类组件:

// 父组件
import React from 'react';  
import ChildComponent from './ChildComponent';  
class ParentComponent extends React.Component {  handleDataFromChild = (data) => {  console.log('Received data from child:', data);  // 在这里处理从子组件接收到的数据  }  render() {  return (  <div>  <ChildComponent onDataReceived={this.handleDataFromChild} />  </div>  );  }  
}  
export default ParentComponent;// 子组件
import React from 'react';  
class ChildComponent extends React.Component {  handleClick = () => {  const data = 'Hello from Child!';  this.props.onDataReceived(data); // 调用父组件传递的回调函数并传递数据  }  render() {  return (  <button onClick={this.handleClick}>Send Data to Parent</button>  );  }  
}  
export default ChildComponent;

兄弟组件传递数据

使用状态提升:父组件维护一个状态(state),这个状态将被传递给两个兄弟组件。

兄弟A数据 => => 兄弟B数据

  1. 兄弟组件A:兄弟组件A通过向父组件传递数据
  2. 父组件:接收兄弟组件A传递过来的数据,并通过 props 传递给 兄弟组件B
  3. 兄弟组件B:接收父组件过来的数据,该数据即为兄弟组件A组件的数据

函数式组件:

// 父组件  
import React, { useState } from 'react';  function ParentComponent() {  const [data, setData] = useState(null);  const handleDataChange = (newData) => {  setData(newData);  };  return (  <div>  <SiblingA onDataChange={handleDataChange} />  <SiblingB data={data} />  </div>  );  
}  // 兄弟组件A  
function SiblingA({ onDataChange }) {  // 假设这里有一个方法触发数据改变  const triggerDataChange = () => {  const newData = 'Hello from Sibling A!';  onDataChange(newData);  };  return (  <button onClick={triggerDataChange}>Send Data to Sibling B</button>  );  
}  // 兄弟组件B  
function SiblingB({ data }) {  return <div>{data}</div>;  
}

类组件:

// 父组件  
class ParentComponent extends React.Component {  state = { data: null };  handleDataChange = (newData) => {  this.setState({ data: newData });  };  render() {  return (  <div>  <SiblingA onDataChange={this.handleDataChange} />  <SiblingB data={this.state.data} />  </div>  );  }  
}  // 兄弟组件A  
class SiblingA extends React.Component {  // 假设这里有一个方法触发数据改变  triggerDataChange = () => {  const newData = 'Hello from Sibling A!';  this.props.onDataChange(newData);  };  render() {  return (  <button onClick={this.triggerDataChange}>Send Data to Sibling B</button>  );  }  
}  // 兄弟组件B  
class SiblingB extends React.Component {  render() {  return <div>{this.props.data}</div>;  }  
}

祖先与后代组件之间的传值

使用 Context API

在使用 React 的 Context API 时,通常会创建一个 Context 对象(例如 MyContext),然后在组件树中的某个位置使用 MyContext.Provider 来包裹那些需要访问 Context 值的组件

  • 这个 MyContext.Provider 通常会放在需要共享数据的最近公共祖先组件中。
  • 确保那些需要访问 Context 值的组件是 Context.Provider后代组件即可。
// SiblingA、SiblingB 的公共祖先组件
// 首先创建 Context  
const MyContext = React.createContext();  // 创建一个 ProviderComponent 组件,它将使用 MyContext.Provider 来提供数据  
function ProviderComponent() {  const [data, setData] = React.useState(null);  return (  <MyContext.Provider value={{ data, setData }}>  {/* 这里是子组件,包括 SiblingA 和 SiblingB,它们可以访问 MyContext 中的值 */}  <SiblingA />  <SiblingB />  </MyContext.Provider>  );  
}  // SiblingA 组件
function SiblingA() {  const { data } = React.useContext(MyContext);  // 使用 useContext 钩子来访问 MyContext 中的 data  return <div>SiblingA: {data}</div>;  
}  // SiblingB 组件
function SiblingB() {  const { setData } = React.useContext(MyContext);  // 使用 useContext 钩子来访问 MyContext 中的 setData  return (  <button onClick={() => setData('新的数据')}>Update Data in SiblingB</button>  );  
}  
  1. <MyContext.Provider value={{ data, setData }}> 组件包裹住 <SiblingA /><SiblingB /> 组件,确保 <MyContext.Provider> 是公共祖先组件
  2. <SiblingA /><SiblingB />即可通过 React.useContext(MyContext) 获取到 MyContext 中的 valuesetData

复杂关系的组件之间的传值

使用发布-订阅模式

当使用 发布-订阅模式 时,一般会使用第三方库 PubSubJS

安装:
npm install pubsub-js --save
yarn add pubsub-js

组件B传递数据给组件A:(即:组件A是订阅者,组件B是发布者,先订阅再发布)

在组件A中:

  • 使用 PubSub.subscribe方法来订阅事件
  • 这个方法接受两个参数:事件名称和一个回调函数,该回调函数将在事件被发布时执行:
    import PubSub from 'pubsub-js;componentDidMount() {  // 订阅一个myEvent事件,当有发布myEvent事件时触发回调从而获取到发布的数据PubSub.subscribe('myEvent', (msg, data) => {  // 处理接收到的数据  console.log(msg, data);  // 'myEvent', { message: 'Hello from another sibling!' }});  
    }  componentWillUnmount() {  // 组件卸载时取消订阅,避免内存泄漏  PubSub.unsubscribe('myEvent', this.handleMyEvent);  
    }
    

在组件B中:

  • 使用 PubSub.publish 方法来发布事件

  • 这个方法接受两个参数:事件名称和要传递的数据:

    import PubSub from 'pubsub-js;handleClick = () => {  // 发布一个myEvent事件,该事件和数据会被订阅myEvent事件的回调捕获PubSub.publish('myEvent', { message: 'Hello from another sibling!' }); 
    };  render() {  return (  <button onClick={this.handleClick}>Publish Event</button>  );  
    }
    

注意:

  1. 当组件卸载时,记得取消订阅事件,以避免潜在的内存泄漏
  2. 通常不建议将其用作复杂关系组件之间传值的主要方式。React自身提供了一套基于 props 和 state 的数据流模型,以及 Context APIRedux 等库来处理更复杂的状态管理

.

使用 Redux

Redux 是一个用于管理 JavaScript 应用程序中状态(state)的库,它提供了一种可预测的方式来更新应用程序的状态,类似 Vue 中的 Vuex。

传送门:

  • Redux (1)

  • Redux (2)

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

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

相关文章

vue怎样获取dom元素?

在 Vue.js 中&#xff0c;直接操作 DOM 元素通常不是推荐的做法&#xff0c;因为 Vue 的核心思想是数据驱动视图&#xff0c;我们更倾向于通过改变数据来影响视图&#xff0c;而不是直接操作 DOM。 然而&#xff0c;在某些情况下&#xff0c;你可能确实需要直接获取和操作 DOM…

C++模板之模板成员函数不能偏特化

目录 1.引言 2.类模板成员函数的特化 2.1.没有函数特化的类模板 2.2.增加函数特化 3.“曲线救国”函数“偏特化” 3.1.函数重载实现“偏特化” 3.2.使用类型选择机制实现“偏特化” 4.总结 1.引言 C 泛型编程的资料在介绍类模板的特化和偏特化的时候&#xff0…

【HarmonyOS】HUAWEI DevEco Studio 下载地址汇总

目录 OpenHarmony 4.x Releases 4.1 Release4.0 Release OpenHarmony 3.x Releases 3.2.1 Release3.2 Release3.1.3 Release3.1.2 Release3.1.1 Release3.1 Release 说明 Full SDK&#xff1a;面向OEM厂商提供&#xff0c;包含了需要使用系统权限的系统接口。 Public SDK&am…

Python对Excel表格的操作

今天, 实现了一个对excel表格操作的技术方案. 操作的要求是: (1)在一个目标表格(表格2)中的第2列已经有唯一标识码.第1列为凭证号, 但是是空的. (2)在数据表格中(表格1)中有资产的信息, 其中第2列是资产的唯一标识码, 第1列是凭证号. (3)表格2内只有部分资产. 要求: 从表格1中…

前端:鼠标点击实现高亮特效

一、实现思路 获取鼠标点击位置 通过鼠标点击位置设置高亮裁剪动画 二、效果展示 三、按钮组件代码 <template><buttonclass"blueBut"click"clickHandler":style"{backgroundColor: clickBut ? rgb(31, 67, 117) : rgb(128, 128, 128),…

C# OpenCvSharp 图像处理函数-图像拼接-hconcat、vconcat、Stitcher

在图像处理和计算机视觉领域,图像拼接是一个常见的操作。OpenCvSharp是一个用于.NET平台的OpenCV封装库,可以方便地进行图像处理。本文将详细介绍如何使用OpenCvSharp中的hconcat、vconcat函数以及Stitcher类进行图像拼接,并通过具体示例帮助读者理解和掌握这些知识点。 函…

Java生成NetCDF文件

因为需要再Cesium中实现风场粒子效果&#xff0c;网上找了许多项目&#xff0c;大多是通过加载NC文件来进行渲染的&#xff0c;因此了解NC文件又成了一件重要的事。特此记录用java成果生成可在前端渲染&#xff0c;QGIS中正常渲染的NetCDF文件的相关代码&#xff08;有没详细整…

16. 第十六章 类和函数

16. 类和函数 现在我们已经知道如何创建新的类型, 下一步是编写接收用户定义的对象作为参数或者将其当作结果用户定义的函数. 本章我会展示函数式编程风格, 以及两个新的程序开发计划.本章的代码示例可以从↓下载. https://github.com/AllenDowney/ThinkPython2/blob/master/c…

java程序在运行过程各个内部结构的作用

一&#xff1a;内部结构 一个进程对应一个jvm实例&#xff0c;一个运行时数据区&#xff0c;又包含多个线程&#xff0c;这些线程共享了方法区和堆&#xff0c;每个线程包含了程序计数器、本地方法栈和虚拟机栈接下来我们通过一个示意图介绍一下这个空间。 如图所示,当一个hell…

内窥镜系统设计简介

内窥镜系统设计简介 1. 源由2. 系统组成2.1 光学系统2.2 机械结构2.3 电子系统2.4 软件系统2.5 安全性和合规性2.6 研发与测试2.7 用户培训与支持 3. 研发过程3.1 光学系统Step 1&#xff1a;镜头设计Step 2&#xff1a;光源Step 3&#xff1a;成像传感器 3.2 机械结构Step 1&a…

11.泛型、trait和生命周期(上)

标题 一、泛型数据的引入二、改写为泛型函数三、结构体/枚举中的泛型定义四、方法定义中的泛型 一、泛型数据的引入 下面是两个函数&#xff0c;分别用来取得整型和符号型vector中的最大值 use std::fs::File;fn get_max_float_value_from_vector(src: &[f64]) -> f64…

代码随想录-Day31

455. 分发饼干 假设你是一位很棒的家长&#xff0c;想要给你的孩子们一些小饼干。但是&#xff0c;每个孩子最多只能给一块饼干。 对每个孩子 i&#xff0c;都有一个胃口值 g[i]&#xff0c;这是能让孩子们满足胃口的饼干的最小尺寸&#xff1b;并且每块饼干 j&#xff0c;都…

Python中的命名空间和作用域:解密变量的可见性和生命周期

在 Python 中&#xff0c;命名空间&#xff08;Namespace&#xff09;和作用域&#xff08;Scope&#xff09;是重要的概念&#xff0c;它们决定了变量和函数的可见性和生命周期。理解命名空间和作用域是编写高效、可维护代码的关键。 基本语法 命名空间 命名空间是一个存储…

新视野大学英语2 词组 6.16

decide between rival options 在互相竞争的选项中做出选择 chinese imperial general 中国帝国将军 on a raid into enemy territory 深入敌方领土突袭 on a raid into&#xff1a;“在进入……的突袭行动中”。 通常指军事行动中快速、秘密地侵入敌人控制的区域&#xff0c…

oracle打补丁

1.备份 su - grid -c "crsctl status res -t" cat /proc/meminfo | grep HugePagesls -lrt /dev/ls -lrt /dev/sd*ls -lrt /dev/asm*cat /etc/udev/rules.d/asm***df -hmountfree -g/etc/security/limits.conf/etc/hosts/etc/selinux/config /etc/pam.d/system-aut…

vs+qt5.0 使用poppler 操作库

Poppler 是一个用来生成 PDF 的C类库&#xff0c;从xpdf 继承而来。vs编译库如下&#xff1a; vs中只需要添加依赖库即可 头文件&#xff1a;

从MySQL到NoSQL:分析传统关系型数据库与NoSQL数据库的协同

引言 数据库是一个系统,用来管理和存储数据的地方。数据在数据库中以一种结构化的方式组织,这样能更容易地查询和处理数据。 关系型数据库是基于关系模型的数据库,它将数据存储在不同的表中,每个表都有各自的独一无二的主键。表与表之间通过共享的数据项相互关联。像MySQ…

windows11 生产力工具配置

一、系统安装 官方windows11.iso镜像文件安装操作系统时&#xff0c;会强制要求联网验证&#xff0c;否则无法继续安装操作系统&#xff0c;跳过联网登录账号的方式为&#xff1a;按下【shiftF10】快捷键&#xff0c;调出cmd命令窗口&#xff0c;输入命令 OOBE\BYPASSNRO 等…

【博客720】时序数据库基石:LSM Tree的辅助优化

时序数据库基石&#xff1a;LSM Tree的辅助优化 场景&#xff1a; LSM Tree其实本质是一种思想&#xff0c;而具体是否需要WAL&#xff0c;内存表用什么有序数据结构来组织&#xff0c;磁盘上的SSTable用什么结构来存放&#xff0c;是否需要布隆过滤器来加快不存在数据的判断等…

Python笔记 - TOML配置文件

TOML&#xff08;Tom’s Obvious, Minimal Language&#xff09;是一种配置文件格式&#xff0c;旨在比JSON、YAML等格式更易读、更人性化。它使用简洁的语法&#xff0c;能清晰地表达复杂的结构&#xff0c;同时保留良好的可读性。本文将介绍TOML的基本语法&#xff0c;提供代…