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.mzph.cn/diannao/61079.shtml

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

相关文章

数据结构树和二叉树知识点和递归序列

二叉树知识点 一.树的概念1.1关于树的名词解释 二.二叉树的概念1. 二叉树性质&#xff1a; 三.满二叉树与完全二叉树递归前序遍历递归中序遍历递归后续遍历 一.树的概念 树是一种非线性数据结构&#xff0c;它是由n个或大于n个的结点来组成具有层次关系的一个集合&#xff08;…

速通前端篇 —— CSS

找往期文章包括但不限于本期文章中不懂的知识点&#xff1a; 个人主页&#xff1a;我要学编程程(ಥ_ಥ)-CSDN博客 所属专栏&#xff1a;速通前端 目录 CSS的介绍 基本语法规范 CSS选择器 标签选择器 class选择器 id选择器 复合选择器 通配符选择器 CSS常见样式 颜…

使用 Elastic 3 步实现基于 OTel 的原生 K8s 和应用可观测性

作者&#xff1a;来自 Elastic Bahubali Shetti Elastic 的 OpenTelemetry 发行版现已支持 OTel Operator&#xff0c;可使用 EDOT SDK 自动检测应用程序&#xff0c;并管理 EDOT OTel Collector 的部署和生命周期以实现 Kubernetes 可观察性。了解如何通过 3 个简单步骤进行配…

stack、queue、priority_queue、deque的使用和模拟实现

目录 1.容器适配器 2.stack stack的常用接口及使用示例 stack的模拟实现 3.queue queue的常用接口及使用示例 queue的模拟实现 4.priority_queue priority_queue的常用接口及使用示例 priority_queue的模拟实现 5.deque 认识deque deque底层的数据结构 deque和ve…

Linux的cuDNN(cudnn)安装教程(CUDA(cuda\cuda toolkit))

CUDA(cuda\cuda toolkit&#xff09;安装教程 https://blog.csdn.net/huiyayaya/article/details/143863835?spm1001.2014.3001.5502官网下载cudnn https://developer.nvidia.com/rdp/cudnn-archive这个下载到自己的电脑 下载到本地就好 复制到服务器 切换到cudnn文件所在目…

Kafka中ACKS LSO LEO LW HW AR ISR OSR解析

名称解释 ACKS&#xff08;Acknowledgments&#xff09;确认、回执 LW&#xff08;Low watermark&#xff09;低水位、LSO&#xff08;Log start offset&#xff09;起始偏移量 HW&#xff08;High watermark&#xff09;高水位 LEO&#xff08;Log end offset&#xff09;…

C++设计模式行为模式———迭代器模式

文章目录 一、引言二、迭代器模式三、总结 一、引言 迭代器模式是一种行为设计模式&#xff0c; 让你能在不暴露集合底层表现形式 &#xff08;列表、 栈和树等&#xff09; 的情况下遍历集合中所有的元素。C标准库中内置了很多容器并提供了合适的迭代器&#xff0c;尽管我们不…

智能体Agent调研

单个智能体建模与优化现状 人类长期以来追求类似于或超越人类水平的人工智能 (AI)&#xff0c;而 基于AI的代理&#xff08;Agent&#xff09;被认为是一个有前途的研究方向。传统计算机领域的Agent有多种&#xff0c;如自动化脚本、网络爬虫、推荐系统、软件机器人能够独立自…

SAP PI/PO Proxy2JDBC SQL_QUERY动态接口示例

目录 背景&#xff1a; 完整demo步骤&#xff1a; IR: ID: SPROXY: 测试代码&#xff1a; 注意点&#xff1a; 背景&#xff1a; 中途临时帮客户项目做其他功能&#xff0c;项目上有部分开发项需要通过PO去第三方数据库取数&#xff0c;项目上的开发对PO不太熟&#xf…

【汇编语言】数据处理的两个基本问题(三) —— 汇编语言的艺术:从div,dd,dup到结构化数据的访问

文章目录 前言1. div指令1.1 使用div时的注意事项1.2 使用格式1.3 多种内存单元表示方法进行举例1.4 问题一1.5 问题一的分析与求解1.5.1 分析1.5.2 程序实现 1.6 问题二1.7 问题二的分析与求解1.7.1 分析1.7.2 程序实现 2. 伪指令 dd2.1 什么是dd&#xff1f;2.2 问题三2.3 问…

模型的评估指标——IoU、混淆矩阵、Precision、Recall、P-R曲线、F1-score、mAP、AP、AUC-ROC

文章目录 预测框的预测指标——IoU&#xff08;交并比&#xff09;分类预测指标混淆矩阵&#xff08;Confusion Matrix&#xff0c;TP、FP、FN、TN)Precision&#xff08;精度&#xff09;Recall&#xff08;召回率&#xff09;P-R曲线F1-scoreTPR、TNR、FPR、FNRROC曲线下面积…

轻量云服务器:入门级云计算的最佳选择

在云计算领域&#xff0c;轻量云服务器逐渐成为小型企业、个人开发者和初创公司关注的热点。它凭借高性价比、简单易用和稳定性能&#xff0c;正在改变传统的服务器部署方式。本文将详细解析轻量云服务器的定义、优势、适用场景及如何选择最佳方案&#xff0c;帮助您全面了解这…

【初阶数据结构篇】归并排序、计数排序

文章目录 须知 &#x1f4ac; 欢迎讨论&#xff1a;如果你在学习过程中有任何问题或想法&#xff0c;欢迎在评论区留言&#xff0c;我们一起交流学习。你的支持是我继续创作的动力&#xff01; &#x1f44d; 点赞、收藏与分享&#xff1a;觉得这篇文章对你有帮助吗&#xff1…

移远通信5G RedCap模组RG255C-CN通过中国电信5G Inside终端生态认证

近日&#xff0c;移远通信5G RedCap模组RG255C-CN荣获中国电信颁发的5G Inside终端生态认证证书。这表明&#xff0c;该产品在5G基本性能、网络兼容性、安全特性等方面已经过严格评测且表现优异&#xff0c;将进一步加速推动5G行业终端规模化应用。 中国电信5G Inside终端生态认…

Towards Reasoning in Large Language Models: A Survey

文章目录 题目摘要引言什么是推理?走向大型语言模型中的推理测量大型语言模型中的推理发现与启示反思、讨论和未来方向 为什么要推理?结论题目 大型语言模型中的推理:一项调查 论文地址:https://arxiv.org/abs/2212.10403 项目地址: https://github.com/jeffhj/LM-reason…

Android Studio | 修改镜像地址为阿里云镜像地址,启动App

在项目文件的目录下的 settings.gradle.kts 中修改配置&#xff0c;配置中包含插件和依赖项 pluginManagement {repositories {maven { urluri ("https://www.jitpack.io")}maven { urluri ("https://maven.aliyun.com/repository/releases")}maven { urlu…

Python | Leetcode Python题解之第564题数组嵌套

题目&#xff1a; 题解&#xff1a; class Solution:def arrayNesting(self, nums: List[int]) -> int:ans, n 0, len(nums)for i in range(n):cnt 0while nums[i] < n:num nums[i]nums[i] ni numcnt 1ans max(ans, cnt)return ans

2024-11-17 -MATLAB三维绘图简单实例

1. x -1:0.05:1; y x; [X, Y] meshgrid(x, y); f (X, Y) (sin(pi * X) .* sin(pi * Y)) .^ 2.*sin(2.*X2.*Y); mesh(X, Y, f(X, Y)); % 调用函数f并传递X和Y xlabel(X-axis); ylabel(Y-axis); zlabel(Z-axis); title(Surface Plot of (sin(pi * X) .* sin(pi * Y)) .^ 2.*…

网络层9——虚拟专用网VPN和网络地址转换NAT

目录 一、为什么有虚拟专用网&#xff1f; 二、如何理解“虚拟专用网”&#xff1f; 三、IP隧道技术实现虚拟专用网 四、网络地址变换 一、为什么有虚拟专用网&#xff1f; 第一&#xff0c;IPv4只有32位&#xff0c;最多有40亿个全球唯一的IP地址数量不够&#xff0c;无法…

小程序如何完成订阅

小程序如何完成订阅 参考相关文档实践问题处理授权弹窗不再触发引导用户重新授权 参考相关文档 微信小程序实现订阅消息推送的实现步骤 发送订阅消息 小程序订阅消息&#xff08;用户通过弹窗订阅&#xff09;开发指南 实践 我们需要先选这一个模板&#xff0c;具体流程参考…