React中组件通信的几种方式

在构建复杂的React应用时,组件之间的通信是至关重要的。从简单的父子组件通信到跨组件状态同步,不同组件之间的通信方式多种多样。

1. 父子组件通信

父子组件通信是 React 中最基本的通信方式之一。在这种模式下,数据是从父组件通过 props 传递给子组件的,子组件接收到 props 后进行渲染或其他操作。

特点:
  • 单向数据流:数据从父组件流向子组件,子组件无法直接修改父组件传递过来的 props。

  • 简单明了:适用于父子组件之间的简单数据传递和交互。

  • 可维护性高:因为数据流清晰,易于追踪和调试。

父组件:

// 父组件import React, { Component } from 'react'
import CChild from "./components/C-Child"export default class CApp extends Component {state = {msg: '这是父组件的数据'}render() {return (<div><h2>父组件</h2><CChild msg={this.state.msg} /></div>)}
}


子组件:

// 子组件
import React, { Component } from 'react'export default class CChild extends Component {render() {return (<div><h4>子组件</h4><p>{this.props.msg}</p></div>)}
}

2. 子父组件通信

子父组件通信是指子组件向父组件传递数据或事件的过程。通常通过在子组件中定义回调函数,并将其作为 props 传递给子组件来实现。

特点:
  • 子组件向父组件传递数据或事件:子组件通过调用父组件传递的回调函数,向父组件传递数据或触发事件

  • 灵活性高:可以在需要的时候向父组件传递数据,实现灵活的交互。

  • PApp 组件定义了一个 callback 方法,这个方法用于接收子组件传递的数据。

父组件 PApp

在 render 方法中,PApp 渲染一个 PChild 子组件,并将 callback 方法作为 cb 属性传递给子组件。

//父组件PApp
import React, { Component } from 'react'
import PChild from './components/PChild'export default class PApp extends Component {state = {msg: ''}callback = (newMsg) => {console.log('拿到子组件的数据: ' + newMsg);this.setState({msg: newMsg})}render() {return (<div><h2>父组件 --- {this.state.msg}</h2>// 将回调函数传递给子组件 <PChild cb={this.callback} /></div>)}
}

子组件 PChild:

  • PChild 组件包含了一个状态 msg,代表子组件的数据。
  • PChild 组件有一个按钮,当按钮被点击时,触发 handler 方法。
  • handler 方法调用了父组件传递的回调函数 cb,并将子组件的状态数据 msg 作为参数传递给父组件。
 //子组件PChild
import React, { Component } from 'react'export default class PChild extends Component {state = {msg: '来自子组件的数据'}// 处理按钮点击事件,调用父组件传递的回调函数handler = () => {this.props.cb(this.state.msg)// 将子组件的数据传递给父组件}render() {return (<div><h4>子组件</h4><button onClick={this.handler}>传递</button></div>)}
}

3. 兄弟组件通信

兄弟组件通信是指不具有直接父子关系的两个组件之间进行数据传递和交互的过程。在 React 中,通常需要通过共享父组件来实现兄弟组件之间的通信。

注意:兄弟组件使用共同的父类作为桥梁,本质是父子之间通信。

  1. BApp 组件

    • BApp 组件是整个应用的父组件,它维护着一个状态 message,初始值为 'hello'

    • 在 render 方法中,BApp 返回了一个包含标题、BrotherA 和 BrotherB 组件的 JSX 结构。

    • 将 message 状态作为 BrotherB 组件的 props 传递给它。

import React, { Component } from 'react';
import BrotherA from "./components/BrotherA";
import BrotherB from "./components/BrotherB";class BApp extends Component {state = {message: 'hello'}// 回调函数,用于更新 message 状态// 注意:React 中状态更新通常使用 setState 方法fn = (newMsg) => {console.log('父组件收到:' + newMsg);this.setState({message: newMsg})}render() {return (<div><h1>父组件</h1>{/* 将 fn 方法作为 props 传递给 BrotherA 组件 */}<BrotherA cb={this.fn} />{/* 将 message 状态作为 props 传递给 BrotherB 组件 */}<BrotherB message={this.state.message} /></div>);}
}export default BApp;
  1. BrotherA 组件
  • 定义了一个局部变量 msg,它的值是字符串 '来自子组件A的数据'。
  • 定义了一个函数 handle,用于处理点击事件。当组件标题被点击时,会调用 props 中传递的 cb 函数,并传递 msg 变量作为参数。
  • 返回一个包含标题的 JSX 结构,在标题上设置了点击事件处理函数为 handle
import React from 'react';const BrotherA = props => {const msg = '来自子组件A的数据'const handle = () => {props.cb(msg)}return (<div><h4 onClick={handle}>子组件A</h4></div>);
};export default BrotherA;
  1. BrotherB 组件

    • BrotherB 组件接收一个名为 message 的 prop,它来自于 BApp 的状态。
    • 在组件中显示了一个标题和 message 的值。
import React from 'react';const BrotherB = props => {return (<div><h4>子组件B -- {props.message}</h4></div>);
};export default BrotherB;

4. 使用Context进行跨层级组件通信

当组件层级较深或通信的组件距离较远时,可以使用React的Context API进行跨层级通信。Context允许我们在组件树中传递数据,而不必手动通过Props一层层传递

创建:
  • 使用 React.createContext() 创建上下文对象
  • 并在组件中使用 Provider 提供数据,
  • 子组件通过 ConsumeruseContext 获取数据。

context.js

import React from 'react';// 创建一个上下文对象
const { Provider, Consumer } = React.createContext();// 导出 Provider 和 Consumer 组件,以便在其他地方使用
export {Provider,Consumer
}

BApp

  1. BApp 组件是一个类组件,它作为数据的提供者,使用 Provider 组件将数据传递给它的子组件。

  2. 在 BApp 组件的 render 方法中,通过 Provider 组件的 value 属性传递了一个名为 message 的状态值

// BApp.jsximport React, { Component } from 'react';
import BrotherB from "./components/BrotherB";import { Provider } from "./context.js";class BApp extends Component {state = {message: 'hello react', // 初始化状态值}render() {return (// 使用 Provider 组件提供数据<Provider value={this.state.message}><div><h1>父组件</h1>{/* 渲染子组件 */}<BrotherB /></div></Provider>);}
}export default BApp;

BrotherB

  1. BrotherB 组件是一个函数组件,它作为数据的消费者,使用 Consumer 组件从上层组件(BApp)获取数据并进行渲染。

  2. BrotherB 组件中,通过 Consumer 组件的子组件函数来接收从 Provider 传递下来的值,并进行相应的渲染。

// BrotherB.jsximport React from 'react';import { Consumer } from '../provider.js';const BrotherB = props => {return (// 使用 Consumer 组件消费数据<Consumer>{value => (<div>{/* 使用从 Provider 传递下来的值进行渲染 */}<h4>子组件B -- {value}</h4></div>)}</Consumer>);
};
export default BrotherB;

补充

在 Consumer 组件内部,我们可以使用函数作为子组件

  1. 使用函数作为子组件:
<Consumer>{value => (// 在这里可以直接使用 value 进行渲染或处理<div><h4>子组件B -- {value}</h4></div>)}
</Consumer>

在这个示例中,<Consumer> 组件的子元素是一个函数,该函数接收 value 参数,这个 value 参数就是从 Provider 传递下来的值。在函数内部,可以直接使用 value 进行渲染或处理。

这种方式适用于在 JSX 内部直接定义渲染逻辑,通常更易读,因为它直接放在了 <Consumer> 标签内部。

这样,就实现了 BApp 组件向 BrotherB 组件传递数据的功能。 Context API 的优点之一就是可以让组件之间直接传递数据,而无需通过 props 一层层地传递,从而简化了组件之间的关系。

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

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

相关文章

丹摩征文活动|丹摩助力selenium实现大麦网抢票

丹摩征文活动&#xff5c;丹摩助力selenium实现大麦网抢票 1.引言 在人工智能飞速发展的今天&#xff0c;丹摩智算平台&#xff08;DAMODEL&#xff09;以其卓越的AI算力服务脱颖而出&#xff0c;为开发者提供了一个简化AI开发流程的强大工具。通过租赁GPU资源&#xff0c;丹…

【计算机网络】协议定制

一、结构化数据传输流程 这里涉及协议定制、序列化/反序列化的知识 对于序列化和反序列化&#xff0c;有现成的解决方案&#xff1a;①json ②probuff ③xml 二、理解发送接收函数 我们调用的所有发送/接收函数&#xff0c;根本就不是把数据发送到网络中&#xff01;本质都是…

大数据-226 离线数仓 - Flume 优化配置 自定义拦截器 拦截原理 拦截器实现 Java

点一下关注吧&#xff01;&#xff01;&#xff01;非常感谢&#xff01;&#xff01;持续更新&#xff01;&#xff01;&#xff01; Java篇开始了&#xff01; 目前开始更新 MyBatis&#xff0c;一起深入浅出&#xff01; 目前已经更新到了&#xff1a; Hadoop&#xff0…

AI行业动态:AGI预测、模型进化与工具革新

本周&#xff0c;人工智能&#xff08;AI&#xff09;领域的新闻层出不穷&#xff0c;从关于通用人工智能&#xff08;AGI&#xff09;何时到来的预测&#xff0c;到模型训练与推理技术的突破&#xff0c;再到各种实用工具的更新迭代&#xff0c;精彩纷呈。让我们一起深入了解这…

vue3 如何调用第三方npm包内部的 pinia 状态管理库方法

抛砖引玉: 如果在开发vue3项目是, 引用了npm第三方包 ,而且这个包内使用了Pinia 状态管理库,那我们如何去调用 npm内部的 Pinia 状态管理库呢? 实际遇到的问题: 今天在制作npm包时遇到的问题,之前Vue2版本的时候状态管理库用的Vuex ,当时调用npm包内的状态管理库很简单,直接引…

AWTK-WIDGET-WEB-VIEW 实现笔记 (4) - Ubuntu

Ubuntu 上实现 AWTK-WIDGET-WEB-VIEW 开始以为很简单&#xff0c;后来发现是最麻烦的。因为 Ubuntu 上的 webview 库是 基于 GTK 的&#xff0c;而 AWTK 是基于 X11 的&#xff0c;两者的窗口系统不同&#xff0c;所以期间踩了几个大坑。 1. 编译 AWTK 在使用 Linux 的输入法时…

C++之内存管理

​ &#x1f339;个人主页&#x1f339;&#xff1a;喜欢草莓熊的bear &#x1f339;专栏&#x1f339;&#xff1a;C入门 目录 前言 一、C/C内存分配 二、 malloc、calloc、realloc、free 三、C内存管理方式 3.1 new/delete 操作内置类型 3.2 new和detele操作自定义类型…

Visual Studio 2017 快捷键设置-批量注释和批量取消注释

一.批量注释设置&#xff1a; 1&#xff09;打开Visual Studio 2017,点击菜单栏中的“工具”&#xff0c;然后选中“选项”&#xff1a; 2&#xff09;选中“键盘”&#xff0c;在“显示命令包含”输入框中输入“注释”&#xff1a; 3&#xff09;选中“编辑&#xff1a;注释选…

从零入门激光SLAM(二十三)——direct_visual_lidar_calibration全型号激光雷达-相机标定包

大家好呀&#xff0c;我是一个SLAM方向的在读博士&#xff0c;深知SLAM学习过程一路走来的坎坷&#xff0c;也十分感谢各位大佬的优质文章和源码。随着知识的越来越多&#xff0c;越来越细&#xff0c;我准备整理一个自己的激光SLAM学习笔记专栏&#xff0c;从0带大家快速上手激…

蓝桥杯备赛(持续更新)

16届蓝桥杯算法类知识图谱.pdf 1. 格式打印 %03d&#xff1a;如果是两位数&#xff0c;将会在前面添上一位0 %.2f&#xff1a;会保留两位小数 如果是long&#xff0c;必须在数字后面加上L。 2. 进制转化 2.1. 十进制转任意进制&#xff1a; 十进制转任意进制时&#xff…

【STL】set,multiset,map,multimap的介绍以及使用

关联式容器 在C的STL中包含序列式容器和关联式容器 1.关联式容器&#xff1a;它里面存储的是元素本身&#xff0c;其底层是线性序列的数据结构&#xff0c;比如&#xff1a;vector&#xff0c;list&#xff0c;deque&#xff0c;forward_list(C11)等 2.关联式容器里面储存的…

螺旋矩阵II(leetcode 59)

转圈过程&#xff08;边界处理&#xff09;遵循循环不变量的原则&#xff0c;坚持一个原则处理每一条边&#xff0c;左闭右开处理 class Solution { public:vector<vector<int>> generateMatrix(int n) {vector<vector<int>> num(n, vector<int>…

MCU的时钟体系

stm32F4的时钟体系图 1MHZ 10^6 HZ 系统时钟频率是168MHZ;AHB1、AHB2、AHB3总线上的时钟频率是168MHz;APB1总线上的时钟频率为42MHz&#xff1b;APB2总线上的时钟频率为84MHz&#xff1b; stm32F4的时钟体系图 在system_stm32f4xx.c文件中查看APB1和APB2的预分频值到底是多少…

走进嵌入式开发世界

目录 一、概述 二、嵌入式开发的核心要素 2.1. 硬件平台选择与设计 2.1.1. 处理器选择 2.1.2. 电路设计 2.1.3.硬件集成与测试 2.2. 软件开发与调试 2.2.1. 编程语言选择 2.2.2. 操作系统与中间件 2.2.3. 软件架构与模块化设计 2.2.4. 调试与测试 三、系统优化与功…

SpringCloud篇(服务网关 - GateWay)

目录 一、简介 二、为什么需要网关 二、gateway快速入门 1. 创建gateway服务&#xff0c;引入依赖 2. 编写启动类 3. 编写基础配置和路由规则 4. 重启测试 5. 网关路由的流程图 6. 总结 三、断言工厂 四、过滤器工厂 1. 路由过滤器的种类 2. 请求头过滤器 3. 默认…

技术理论||02空中三角测量

空中三角测量指的是根据少量控制点坐标,利用空间前后交汇,对六个外方位要素进行解算,从而获得大量未知点坐标及图像外方位要素。空三测量精度是整个摄影测量过程中的关键环节,空三解算的精度直接影响到数字正射图像、实景三维模型等数字化成果的质量。在空三加密的平差解算中,主…

OpenTelemetry 赋能DevOps流程的可观测性革命

作者&#xff1a;天颇 引言 在当今快节奏的软件开发和运维环境中&#xff0c;DevOps 已经成为主流&#xff0c;它通过整合开发和运维流程&#xff0c;推动着软件的快速迭代和持续交付。然而&#xff0c;随着微服务、容器化和云计算等技术的普及&#xff0c;系统复杂性急剧增加…

大数据如何助力干部选拔的公正性

随着社会的发展和进步&#xff0c;干部选拔成为组织管理中至关重要的一环。传统的选拔方式可能存在主观性、不公平性以及效率低下等问题。大数据技术的应用&#xff0c;为干部选拔提供了更加全面、精准、客观的信息支持&#xff0c;显著提升选拔工作的科学性和公正性。以下是大…

风电电力系统低碳调度论文阅读第一期

在碳交易市场中&#xff0c;历史法和基准线法是用于分配碳排放配额的两种主要方法。以下是两种方法的公式及其解释&#xff1a; 区别总结 历史法&#xff1a;基于历史排放量&#xff0c;分配具有较强的公平性但可能缺乏激励减排。基准线法&#xff1a;基于行业基准和生产量&am…

PHP代码审计 --MVC模型开发框架rce示例

MVC模型开发框架 控制器Controller&#xff1a;负责响应用户请求、准备数据&#xff0c;及决定如何展示数据 模块Model&#xff1a;管理业务逻辑和数据库逻辑&#xff0c;提供链接和操作数据库的抽象层 视图View&#xff1a;负责前端模板渲染数据&#xff0c;通过html呈现给用户…