【react从入门到精通】React父子组件通信方式详解(有示例)

news2024/11/19 21:23:18

文章目录

  • 前言
  • React技能树
  • 通过 props 实现父子组件通信
  • 通过 state 实现父子组件通信
  • 通过回调函数实现父子组件通信
  • 使用 React Context 实现组件通信
  • 总结
  • 写在最后

在这里插入图片描述

前言

在上一篇文章《JSX详解》中我们了解了什么是jsx以及jsx的语法规则。

本文中我们将详细了解React父子组件通信方式。

React技能树

React 技能树
├── JSX
│   ├── 语法
│   ├── 元素渲染
│   ├── 组件
│   ├── Props
│   ├── State
│   └── 生命周期
├── 组件通信
│   ├── 父子组件通信
│   ├── 兄弟组件通信
│   ├── 跨级组件通信
│   ├── Context
│   └── Redux
├── 样式
│   ├── 内联样式
│   ├── CSS Modules
│   └── Styled Components
├── 路由
│   ├── React Router
│   ├── 动态路由
│   └── 嵌套路由
├── 数据请求
│   ├── Axios
│   ├── Fetch
│   └── GraphQL
├── 状态管理
│   ├── Redux
│   ├── MobX
│   └── Recoil
├── 常用库和框架
│   ├── Ant Design
│   ├── Material UI
│   ├── Bootstrap
│   ├── Semantic UI
│   └── Tailwind CSS
├── 测试
│   ├── Jest
│   ├── Enzyme
│   └── React Testing Library
├── 构建工具
│   ├── Webpack
│   └── Parcel
└── 服务端渲染
    ├── Next.js
    └── Gatsby

通过 props 实现父子组件通信

React 组件之间的数据传递通常是通过 props 实现的。组件可以将数据作为 props 属性传递给其子组件,然后子组件可以使用这些数据来进行渲染或执行操作。

在下面的示例中,我们将展示如何通过 props 实现父子组件之间的通信。

我们创建一个包含两个组件的简单 React 应用程序:一个父组件 Parent 和一个子组件 Child。父组件有一个按钮,点击按钮将触发一个事件,事件将向子组件传递一个字符串类型的消息。子组件将通过 props 属性接收消息并在页面上显示。

// Parent.js

import React from 'react';
import Child from './Child';

class Parent extends React.Component {
  constructor(props) {
    super(props);

    this.state = {
      message: '',
    };

    this.handleButtonClick = this.handleButtonClick.bind(this);
  }

  handleButtonClick() {
    this.setState({
      message: 'Hello from Parent!',
    });
  }

  render() {
    return (
      <div>
        <h1>Parent Component</h1>
        <button onClick={this.handleButtonClick}>Click me</button>
        <Child message={this.state.message} />
      </div>
    );
  }
}

export default Parent;
// Child.js

import React from 'react';

class Child extends React.Component {
  render() {
    return (
      <div>
        <h2>Child Component</h2>
        <p>{this.props.message}</p>
      </div>
    );
  }
}

export default Child;

在上述代码中,我们创建了一个 Parent 组件和一个 Child 组件,并将 Child 组件作为 Parent 组件的子组件进行渲染。

Parent 组件有一个按钮,并且通过 state 管理一个 message 状态。当按钮被点击时,Parent 组件会更新 message 状态,然后将 message 作为 props 属性传递给 Child 组件。Child 组件接收 message 属性并将其显示在页面上。

通过 state 实现父子组件通信

在某些情况下,组件之间的通信需要更为复杂的逻辑。在这种情况下,可以使用组件的状态来实现通信。子组件可以通过 props 属性接收来自父组件的数据,并将其存储在自己的状态中。然后,子组件可以通过 setState 方法更新自己的状态,并触发重新渲染。

在下面的示例中,我们将展示如何通过状态实现父子组件之间的通信。

我们创建一个父组件 Parent 和一个子组件 Child。父组件有一个按钮,点击按钮将触发一个事件,事件将更新父组件的状态并将其作为 props 属性传递给子组件。子组件将使用接收到的 props 属性来更新自己的状态,并在页面上显示。

// Parent.js

import React from 'react';
import Child from './Child';

class Parent extends React.Component {
  constructor(props) {
    super(props);

    this.state = {
      message: '',
    };

    this.handleButtonClick = this.handleButtonClick.bind(this);
  }

  handleButtonClick() {
    this.setState({
      message: 'Hello from Parent!',
    });
  }

  render() {
    return (
      <div>
        <h1>Parent Component</h1>
        <button onClick={this.handleButtonClick}>Click me</button>
        <Child message={this.state.message} />
      </div>
    );
  }
}

export default Parent;
// Child.js

import React from 'react';

class Child extends React.Component {
  constructor(props) {
    super(props);

    this.state = {
      message: '',
    };

    this.handleButtonClick = this.handleButtonClick.bind(this);
  }

  handleButtonClick() {
    this.setState({
      message: 'Hello from Child!',
    });
  }

  render() {
    return (
      <div>
        <h2>Child Component</h2>
        <p>{this.props.message}</p>
        <button onClick={this.handleButtonClick}>Click me</button>
        <p>{this.state.message}</p>
      </div>
    );
  }
}

export default Child;

在上述代码中,我们创建了一个 Parent 组件和一个 Child 组件,并将 Child 组件作为 Parent 组件的子组件进行渲染。

Parent 组件有一个按钮,并且通过 state 管理一个 message 状态。当按钮被点击时,Parent 组件会更新 message 状态,然后将 message 作为 props 属性传递给 Child 组件。Child 组件接收 message 属性并将其显示在页面上。

同时,Child 组件也有一个按钮,当按钮被点击时,Child 组件会更新自己的状态并将其显示在页面上。

通过回调函数实现父子组件通信

有时候,我们需要将子组件中的数据传递回父组件,以便父组件可以执行一些操作或更新自己的状态。在这种情况下,可以通过将回调函数作为 props 属性传递给子组件来实现通信。子组件可以调用该回调函数,并将需要传递的数据作为参数传递给它。

在下面的示例中,我们将展示如何通过回调函数实现父子组件之间的通信。

我们创建一个父组件 Parent 和一个子组件 Child。子组件有一个输入框,当输入框中的值发生变化时,子组件将调用传递给它的回调函数,并将输入框中的值作为参数传递给它。父组件将接收到传递的值,并将其存储在自己的状态中。

// Parent.js

import React from 'react';
import Child from './Child';

class Parent extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            inputValue: '',
        };

        this.handleInputChange = this.handleInputChange.bind(this);
    }

    handleInputChange(value) {
        this.setState({
            inputValue: value,
        });
    }

    render() {
        return (
            <div>
                <h1>Parent Component</h1>
                <Child onInputChange={this.handleInputChange} />
                <p>Input value: {this.state.inputValue}</p>
            </div>
        );
    }
}

export default Parent;

```jsx
// Child.js

import React from 'react';

class Child extends React.Component {
  constructor(props) {
    super(props);

    this.handleInputChange = this.handleInputChange.bind(this);
  }

  handleInputChange(event) {
    const value = event.target.value;
    this.props.onInputChange(value);
  }

  render() {
    return (
      <div>
        <h2>Child Component</h2>
        <input type="text" onChange={this.handleInputChange} />
      </div>
    );
  }
}

export default Child;

在上述代码中,我们创建了一个父组件 Parent 和一个子组件 Child,并将 Child 组件作为 Parent 组件的子组件进行渲染。

Child 组件有一个输入框,并且通过 props 属性将一个回调函数 onInputChange 传递给 Parent 组件。当输入框中的值发生变化时,Child 组件将调用 onInputChange 回调函数,并将输入框中的值作为参数传递给它。Parent 组件接收到传递的值,并将其存储在自己的状态中。同时,Parent 组件将输入框中的值显示在页面上。

使用 React Context 实现组件通信

在某些情况下,如果您需要将数据传递给多个组件,或者您的组件层级很深,那么通过 props 属性将数据从一个组件传递到另一个组件可能会变得很繁琐。在这种情况下,可以使用 React Context 来共享数据并在组件之间进行通信。

React Context 是 React 16.3 版本中引入的一项新功能,它允许您在组件树中传递数据,而无需显式地通过 props 属性将数据传递下去。

使用 React Context,您可以创建一个“上下文”对象,其中包含需要共享的数据,然后将其传递给 React 组件树中的所有组件。这样,任何组件都可以访问该数据,而不需要通过 props 属性进行传递。

下面的示例演示了如何使用 React Context 实现组件通信。

我们创建了一个 ThemeContext 上下文对象,其中包含一个名为 theme 的属性。然后,我们创建了两个组件 Toolbar 和 Button。Toolbar 组件将从 ThemeContext 上下文中获取 theme 属性,并将其作为 props 属性传递给 Button 组件。Button 组件将使用接收到的 theme 属性来渲染自己的样式。

// ThemeContext.js

import React from 'react';

const ThemeContext = React.createContext('light');

export default ThemeContext;
// Toolbar.js

import React from 'react';
import Button from './Button';
import ThemeContext from './ThemeContext';

class Toolbar extends React.Component {
  render() {
    return (
      <div>
        <h1>Toolbar Component</h1>
        <Button />
      </div>
    );
  }
}

Toolbar.contextType = ThemeContext;

export default Toolbar;
// Button.js

import React from 'react';
import ThemeContext from './ThemeContext';

class Button extends React.Component {
  render() {
    const theme = this.context;

    return (
      <button style={{ background: theme === 'dark' ? '#000' : '#fff', color: theme === 'dark' ? '#fff' : '#000' }}>
        {theme === 'dark' ? 'Dark' : 'Light'} Button
      </button>
    );
  }
}

Button.contextType = ThemeContext;

export default Button;

在上述代码中,我们创建了一个名为 ThemeContext 的上下文对象,并将其导出为默认模块。我们还创建了两个组件 Toolbar 和 Button。Toolbar 组件是一个简单的组件,它包含一个标题和一个 Button 组件。

在 Toolbar 组件中,我们将 ThemeContext 上下文对象分配给了 contextType 类型的 static 类属性。这告诉 React,我们希望 Toolbar 组件可以访问 ThemeContext 上下文对象。然后,我们在 Toolbar 组件的 render 方法中,通过 this.context 属性访问 ThemeContext 上下文中的 theme 属性,并将其作为 props 属性传递给 Button 组件。

在 Button 组件中,我们也将 ThemeContext 上下文对象分配给了 contextType 类型的 static 类属性。然后,在 render 方法中,我们使用 this.context 属性访问 ThemeContext 上下文对象,并根据 theme 属性渲染不同的样式。

最后,我们可以在 App 组件中使用 ThemeContext.Provider 组件提供 theme 属性。任何在 ThemeContext.Provider 组件之下的组件都可以通过 contextType 类型的 static 类属性访问 ThemeContext 上下文对象,从而共享 theme 属性。

// App.js

import React from 'react';
import ThemeContext from './ThemeContext';
import Toolbar from './Toolbar';

class App extends React.Component {
  constructor(props) {
    super(props);

    this.state = {
      theme: 'light',
    };

    this.toggleTheme = this.toggleTheme.bind(this);
  }

  toggleTheme() {
    this.setState((state) => ({
      theme: state.theme === 'light' ? 'dark' : 'light',
    }));
  }

  render() {
    return (
      <div>
        <h1>App Component</h1>
        <button onClick={this.toggleTheme}>Toggle Theme</button>
        <ThemeContext.Provider value={this.state.theme}>
          <Toolbar />
        </ThemeContext
      </div>
    );
  }
}
export default App;

在上述代码中,我们在 App 组件中创建了一个名为 theme 的状态,其默认值为 light。我们还创建了一个 toggleTheme 方法,该方法在点击按钮时切换 theme 状态的值。

render 方法中,我们使用 ThemeContext.Provider 组件提供了 theme 属性。该组件将 Toolbar 组件包装在其内部,从而使 Toolbar 组件和 Button 组件都可以访问 ThemeContext 上下文对象,并使用 theme 属性渲染不同的样式。

最后,我们将 App 组件导出为默认模块,以便在其他文件中使用它。

这是一个简单的示例,演示了如何在 React 中使用上下文实现组件通信。当需要在组件树中的多个组件之间共享数据时,使用上下文是一种非常有用的技术。

总结

在React中,父子组件最常用的4种通信方式:

  • 通过 props 实现父子组件通信
  • 通过 state 实现父子组件通信
  • 通过回调函数实现父子组件通信
  • 使用 React Context 实现组件通信

在项目实战过程中,可根据实际情况选择最合适的通信方式。

写在最后

✨原创不易,希望各位大佬多多支持。

👍点赞,你的认可是我创作的动力。

⭐️收藏,感谢你对本文的喜欢。

✏️评论,你的反馈是我进步的财富。

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

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

相关文章

详解SpringBoot外部化配置

SpringBoot外部化配置&#xff08;基于2.4.0以后&#xff09; Spring Boot可以让你将配置外部化&#xff0c;这样你就可以在不同的环境中使用相同的应用程序代码。 你可以使用各种外部配置源&#xff0c;包括Java properties 文件、YAML文件、环境变量和命令行参数。 属性值可…

【刷题笔记】二维数组地址计算+算法分析+进制转换

目录 一、二维数组地址计算 题目&#xff1a; 分析&#xff1a; 解答&#xff1a; 二、算法分析举例 题目&#xff1a; 分析&#xff1a; 解答&#xff1a; 三、进制转换 题目&#xff1a; 分析&#xff1a; 解答&#xff1a; 一、二维数组地址计算 题目&#xff…

3.19 makefile用法及变量(自定义变量、自动变量、隐含变量)

目录 makefile概述 makefile创建变量的目的 自定义变量 makefile变量的赋值 自动变量 makefile隐含变量 makefile概述 makefile重要性 会不会写makefile&#xff0c;从一个侧面说明了一个人是否具备完成大型工程的能力 make是一个命令工具&#xff0c;是一个解释makefil…

Docker高频使用命令总结(镜像与容器命令)

目录 一.Docker常用命令总结 1.镜像命令管理 2.容器命令管理 二.Docker镜像操作命令 1.docker search&#xff1a;搜索镜像 2.docker pull&#xff1a;下载镜像 3.docker push&#xff1a;上传镜像 4.docker images&#xff1a;查看本地镜像 5.docker inspect &#x…

全球最大蒸馏体量干邑集团,邀请酣客老王讲授产品设计大师课

酒作为文化符号,寄托着全人类的精神追求,与历史、艺术为伍,充当着国际间友好交流的使者。为了弘扬中国白酒文化,把品质卓越的中国酱酒带到全世界,也为了给中国的烈酒爱好者讲清中外烈酒之间的工艺与文化差异,酣客君丰发起了“中国酱酒世界行”,不远万里探访欧洲各国名酒产区,一…

Flutter学习之旅 -网格布局

GridView列表三种形式 可以通过GridView.count实现网格布局 /* 格式: GridView.count(crossAxisCount: 一行显示数量,children: [component(),...],) */ class MyHomePage extends StatelessWidget {const MyHomePage({Key? key}) : super(key: key);overrideWidget build(B…

如何利用问卷工具助力活动开展,实现高效数据收集?

问卷调查是一种常用的活动开展方式&#xff0c;它可以帮助我们更好地了解参与者的需求和意见&#xff0c;为活动的开展提供有力的参考和依据。 1、了解期望和需求&#xff1a;在活动中&#xff0c;我们可以事先通过问卷调查了解参与者的需求、意见、对活动的需求和期望&#x…

PCB制板之前的DFM分析

PCB制板之前的DFM分析 1.华秋DFM分析2.AD18输出IPC文件3.华秋DFM分析开短路 1.华秋DFM分析 1.打开华秋DFM软件&#xff0c;目前先用这软件做DFM分析&#xff0c;主要是简单容易上手操作&#xff0c;并且分析完成之后可以一键下单。 2.将输出的gerber文件导入华秋DFM这个软件…

ubuntu18.04 + 3060 安装测试

分区 在这里&#xff0c;我们进行手动分区&#xff0c;假设你留出的空闲分区为 80G&#xff0c;点击空闲盘符&#xff0c;点击""进行分区&#xff0c;如下&#xff1a; 1&#xff09;efi&#xff1a;如果是单硬盘&#xff0c;在唯一的一个空闲分区上添加&#xff0…

为项目创建Qframework!

liangxiegame/QFramework: Unity3D System Design Architecture (github.com) 下载这个download 在unity中打开&#xff01; 就可以啦 ———— 这里总结一下UI和自动脚本两个非常常用的功能&#xff1a; UI https://www.bilibili.com/video/BV1QK411m7g4/?spm_id_from…

美格智能发布基于高通QCS8550处理器的高算力AI模组SNM970,定义未来终端新体验

近日&#xff0c;全球领先的无线通信模组及解决方案提供商美格智能发布了高算力AI模组SNM970。该产品是行业首批基于高通QCS8550处理器开发的AI模组产品&#xff0c;并凭借卓越的8核高通Kryo™ CPU、综合AI算力高达48Tops、支持Wi-Fi 7等特性&#xff0c;助力将运算效能和灵活性…

【Go Web开发】Web初识、RESTful架构和RESTful API详解、Gin框架的安装和简单使用

博主简介&#xff1a;努力学习的大一在校计算机专业学生&#xff0c;热爱学习和创作。目前在学习和分享&#xff1a;数据结构、Go&#xff0c;Java等相关知识。博主主页&#xff1a; 是瑶瑶子啦所属专栏: Go语言核心编程近期目标&#xff1a;写好专栏的每一篇文章 文章目录 一、…

YonLinker连接集成平台构建新一代产业互联根基

近日&#xff0c;由用友公司主办的“2023用友BIP技术大会“在用友产业园&#xff08;北京&#xff09;盛大召开&#xff0c;用友介绍了更懂企业业务的用友BIP-iuap平台&#xff0c;并发布了全面数智化能力体系&#xff0c;助力企业升级数智化底座&#xff0c;加强加速数智化推进…

入门机器学习,华盛顿大学4个案例分享

机器学习是一门从数据中研究算法的多领域交叉学科&#xff0c;研究计算机如何模拟或实现人类的学习行为。现在&#xff0c;我们可以看到很多机器学习的实际应用&#xff0c;例如语音搜索技术、图像识别、自动翻译、自动驾驶汽车等。机器学习已经成为许多行业的焦点&#xff0c;…

【学习笔记】GeoServer——使用Java发布图层(SHP文件和DB数据库),附自用工具类

文章目录 SHP文件发布逻辑 1、获取到geoserver的manager对象2、调用createWorkArea方法&#xff0c;参入manager&#xff0c;创建空间空间 workArea3、调用createShpDataPool方法&#xff0c;创建数据存储4、发布样式Style.5、发布图层 调用业务层库发布shp文件图层业务逻辑如下…

Ambari 2.7.5+HDP3.1.5离线扩容不同配置组

确保ambari server节点启动&#xff0c;Httpd 服务安装并启动&#xff0c;可参考&#xff1a; Ambari 2.7.5HDP3.1.5离线安装详细教程&#xff08;附安装包&#xff09;https://blog.csdn.net/QYmufeng/article/details/122827261 1.安装ambari agent 在需要添加的主机上安装…

吴恩达与OpenAI官方合作的ChatGPT提示工程课程笔记

吴恩达与OpenAI官方合作的ChatGPT提示工程课程笔记 &#x1f978; 下述代码均在煮皮特上运行喔 LLMs(large language models) Base LLM&#xff1a;基于文本训练数据来预测做“文字接龙” Instruction Tuned LLM&#xff08;指令调整型LLM&#xff09;:接受了遵循指示的培训&am…

SpringBoot 集成 RocketMQ

项目地址 前面我们介绍了怎么使用 docker 安装 rocketMQ&#xff0c;现在我们就来试试使用 SpringBoot 集成之后&#xff0c;怎么发送消息和消费消息。 集成步骤 工程结构 第一步&#xff1a;引入相关依赖 <dependency><groupId>org.projectlombok</groupId…

【新星计划-2023】什么是OSI七层模型?一文带你了解

一、什么是OSI七层模型 OSI七层模型又叫做“OSI参考模型”&#xff0c;它的全称为“开放系统互连参考模型”&#xff0c;它是一个七层的、抽象的模型体&#xff0c;不仅包括一系列抽象的术语或概念&#xff0c;也包括具体的协议。那么为什么会出现OSI参考模型&#xff1f; 原…