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.mfbz.cn/a/713631.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Day01_Ajax入门

文章目录 学习目标一、AJAX 概念和 axios 使用1. 目标2. 讲解2.1 什么是 AJAX ?2.2 什么是服务器&#xff1f;2.3 为何学 AJAX ?2.4 怎么学 AJAX ?2.5 例子2.6 axios语法 二、认识 URL1. 目标2. 讲解2.1 为什么要认识 URL ?2.2 什么是 URL &#xff1f;2.3 URL的组成 &…

架构设计 - WEB项目的基础序列化配置

摘要&#xff1a;web项目中做好基础架构(redis&#xff0c;json)的序列化配置有重要意义 支持复杂数据结构&#xff1a;Redis 支持多种不同的数据结构&#xff0c;如字符串、哈希表、列表、集合和有序集合。在将这些数据结构存储到 Redis 中时&#xff0c;需要将其序列化为字节…

IT入门知识博客文章大纲(0/10)

IT入门知识博客文章大纲 引言 什么是IT&#xff1f; 信息技术&#xff08;Information Technology&#xff09;&#xff0c;互联网技术是指在计算机技术的基础上开发建立的一种信息技术 。互联网技术通过计算机网络的广域网使不同的设备相互连接&#xff0c;加快信息的传输速度…

【JavaEE精炼宝库】多线程(6)线程池

目录 一、线程池的概念及优势 1.1 线程池的概念&#xff1a; 1.2 线程池的优势&#xff1a; 二、工厂模式 三、标准库中的线程池 3.1 标准库线程池参数解释&#xff1a; 3.1.1 corePoolSize | maximumPoolSize&#xff1a; 3.1.2 keepAliveTime | unit&#xff1a; 3.1…

Vue50-mixin混入

一、为什么要使用 mixin混入 两个组件共享一个配置。 二、使用 mixin混入 2-1、创建一个混合js文件 2-2、引入混合js文件 1、局部混合 在每个组件中都引入混合js文件 注意&#xff1a; 混合就是复用配置&#xff0c;vm实例中的所有的配置项&#xff0c;都能在混合.js文件中写…

【计算机毕业设计】基于Springboot的毕业生实习与就业管理系统【源码+lw+部署文档】

包含论文源码的压缩包较大&#xff0c;请私信或者加我的绿色小软件获取 免责声明&#xff1a;资料部分来源于合法的互联网渠道收集和整理&#xff0c;部分自己学习积累成果&#xff0c;供大家学习参考与交流。收取的费用仅用于收集和整理资料耗费时间的酬劳。 本人尊重原创作者…

新旧torch中傅里叶变换实现(fft)

由泰勒级数我们知道&#xff0c;一个函数可以被分解成无穷个幂函数叠加的形式&#xff0c;于是同样地&#xff0c;一个周期函数也可以被分解成多个周期函数叠加&#xff0c;于是自然而然地&#xff0c;三角函数符合这个需求&#xff0c;由傅里叶级数我们可以将周期函数分解成无…

Qwen2大语言模型微调、导出、部署实践

上篇文章&#xff1a; Qwen1.5大语言模型微调实践_qwen1.5 7b微调-CSDN博客 我们介绍了Qwen1.5 大语言模型使用LLaMA-Factory 来微调&#xff0c;这篇文章我们介绍一下微调后模型的导出、部署。 一、模型导出 在webui 界面训练好模型之后点击“Export”选项卡&#xff0c;然…

linux 部署瑞数6实战(维普,药监局)第一部分

声明 本文章中所有内容仅供学习交流使用&#xff0c;不用于其他任何目的&#xff0c;抓包内容、敏感网址、数据接口等均已做脱敏处理&#xff0c;严禁用于商业用途和非法用途&#xff0c;否则由此产生的一切后果均与作者无关&#xff01;wx 本文章未经许可禁止转载&…

ICML24麻省理工提出使用更少的条件独立性测试来发现因果关系新方法

【摘要】众多科学领域的核心问题围绕着理解因果关系这一基本问题。然而,大多数基于约束的因果发现算法,包括广受欢迎的PC算法,通常会进行指数级数量的条件独立性(CI)测试,在各种应用中造成局限。为解决这一问题,我们的工作重点是表征在减少CI测试数量的情况下,可以了解潜在因果…

POC EXP | woodpecker插件编写

woodpecker插件编写 目录 woodpecker介绍woodpecker使用插件编写 安装环境 woodpecker-sdkwoodpecker-request 创建Maven项目 Confluence OGNL表达式注入漏洞插件编写 创建Package包和Class类编写POC 漏洞POC代码编写导出jar包将jar包放入woodpecker的plugin目录运行woodpeck…

UML与设计模式

1、关联关系 关联关系用于描述不同类的对象之间的结构关系&#xff0c;它在一段时间内将多个类的实例连接在一起。关联关系是一种静态关系&#xff0c;通常与运行状态无关&#xff0c;而是由“常识”、“规则”、“法律”等因素决定的&#xff0c;因此关联关系是一种强关联的关…

MPC质心跟随控制(CoM Tracking Control)

MPC质心跟随 在人形机器人中,质心(CoM)的跟随控制是保持机器人稳定和协调运动的关键技术之一。模型预测控制(MPC)是一种先进的控制方法,通过解决在线优化问题来控制机器人质心的位置和速度。下面我们详细介绍如何使用MPC实现质心跟随控制。 MPC基本原理 模型预测控制是…

Iptables深入浅出

1、iptables的基本概念 众所周知iptables是Linux系统下自带免费的包过滤防火墙。其实不然&#xff0c;iptables其实不是真正的防火墙&#xff0c;我们可以把它理解成一个客户端代理&#xff0c;用户通过iptables这个代理&#xff0c;将用户的安全设定执行到对应的”安全框架”…

微软正在推动 OpenAI 转变为营利性公司!Sam Altman 或拥有更多股权 股东也“逼宫”保时捷

目前&#xff0c;OpenAI估值为860亿美元&#xff0c;转型为营利性公司或加速OpenAI IPO&#xff0c;微软及其他投资者认为&#xff0c;若 Altman拥有更多股权&#xff0c;可能就不会那么有动力专注于其他项目和投资其他AI公司。 根据The Information最新报道&#xff0c;Sam A…

C# TextBox模糊查询及输入提示

在程序中&#xff0c;我们经常会遇到文本框中不知道输入什么内容&#xff0c;这时我们可以在文本框中显示提示词提示用户&#xff1b;或者需要查询某个内容却记不清完整信息&#xff0c;通常可以通过文本框列出与输入词相匹配的信息&#xff0c;帮助用户快速索引信息。 文本框…

java打印helloworld

源代码 public class Function1 {public static void main(String[] args) {System.out.println("hello world");}} 打印结果

llama3-70B体验

NVIDIA LLAMA3-70B大模型体验地址&#xff1a; NVIDIA NIM | llama3-70b 问题几个关于宇宙的问题&#xff0c;答案挺有意思的&#xff0c;很有启发性&#xff0c;记录一下&#xff1a; 问题1&#xff1a;既然相对论认为时间是相对的&#xff0c;为何却说宇宙寿命有137亿年&a…

Luma AI如何注册:文生视频领域的新星

文章目录 Luma AI如何注册&#xff1a;文生视频领域的新星一、Luma 注册方式二、Luma 的效果三、Luma 的优势四、Luma 的功能总结 Luma AI如何注册&#xff1a;文生视频领域的新星 近年来&#xff0c;Luma AI 凭借其在文生视频领域的创新技术&#xff0c;逐渐成为行业的新星。…

如何设计网站

设计网站是一个复杂而又有趣的过程。一个好的网站设计不仅可以吸引用户的注意力&#xff0c;还能提供良好的用户体验。下面我将分享一些关于如何设计网站的基本原则。 首先&#xff0c;需要明确网站的目标和受众。在设计网站之前&#xff0c;你应该明确你的网站的目标是什么。你…