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

2023-11-11


在这里插入图片描述

人工智能福利文章

前言

在上一篇文章《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 实现组件通信

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

写在最后

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

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

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

  • 在 `data:` URI 中转义 SVG 的正确方法?

    Chrome 最近已启动使用换行符阻止 URL 和 lt 人物 https www chromestatus com features 5735596811091968 我维护的应用程序严重依赖数据 URI 中的 SVG 图像 data i
  • 如何在Rails 中使用highlight.js?

    我正在尝试在我的 Rails 应用程序中使用语法突出显示和highlight js height js 的说明如下 https github com isagalaev highlight js https github com isaga
  • 每 x 秒重复一次代码,但如果 [在此处插入检查] 则不重复

    这是后续这个问题 https stackoverflow com questions 13304471 javascript get code to run every minute 我在那里找到了如何使代码每 x 秒重复一次 是否有可能举
  • 超出 Google 电子表格上的 ImportXML 限制

    我现在陷入了 抓取问题 特别是我想将作者的姓名从网页提取到谷歌电子表格 其实功能 IMPORTXML A2 span class author vcard meta item 正在工作 但是当我增加了要抓取的链接数量后 它就开始无限加载 所
  • 我应该选择哪个 redux 中间件?

    按照指南 我发现了一些用于 redux 应用程序的中间件 Redux 重击 https github com gaearon redux thunk Redux 承诺 https github com acdlite redux promi
  • Collada 模型面在 Three.js 中无法正确显示

    将 collada 模型导入到 Three js 后 模型的某些面只能从模型内部看到 从外部看不到 如何解决相关面孔的问题 是否可以让模特的脸部从两侧都可见 它无法正常工作的原因是您的文件设置了此双面标志
  • Protractor - 等待多个元素

    我正在尝试等待页面上的多个元素 我不知道可能有多少个 但至少会有一个 我知道使用以下命令等待单个元素 效果很好 var EC protractor ExpectedConditions browser wait EC presenceOf
  • jQuery 或 JavaScript 中的“$”符号是什么意思? [复制]

    这个问题在这里已经有答案了 可能的重复 JavaScript 中 符号的含义是什么 https stackoverflow com questions 1150381 what is the meaning of sign in javas
  • javascript获取网页中选定文本的段落

    突出显示文本后 我想获取所选文本所在的段落 var select window content document getSelection 请问有什么指点吗 这实际上很难做到 因为你必须考虑六种情况 所选内容不在一个段落内 简单 整个选择都
  • React hook useState 未随 onSubmit 更新

    我目前在将输入字段值推至 onSubmit 状态时遇到问题 代码沙箱 https codesandbox io s 8z8xvwk3z2 我正在尝试将输入字段值设置为状态 以便在更新组件后我可以使用该值将用户重定向到另一个页面 我手动测试了
  • 将压缩的json数据存储在本地存储中

    我想将 JSON 数据存储在本地存储中 有时存储的数据可能超过 5MB 每个域的浏览器允许的最大阈值 无论如何 我可以压缩或压缩数据并将其存储在本地存储中吗 如果对大数据进行每个 JS 函数的压缩和解压 会增加多少延迟 我正在使用这个 js
  • Discord.js v12:如何等待 DM 通道中的消息?

    这是我尝试过的代码 message author dmChannel awaitMessages msg gt console log msg content 但它返回此错误消息 TypeError Cannot read property
  • 如何使用 JavaScript 禁用滚动条?

    当我仅在 Internet Explorer 7 中显示代表模式窗口的 div 时 我需要锁定浏览器滚动条 谷歌搜索我发现我可以使用document body style overflow hidden 但这不适用于 IE7 我也尝试过do
  • 变量值的 swap() 函数[重复]

    这个问题在这里已经有答案了 我无法达到下面这个交换函数的预期结果 我希望将值打印为 3 2 function swap x y var t x x y y t console log swap 2 3 任何线索将不胜感激 您的函数正在内部交
  • 带有子节点的拖放区域

    我有一个带有多个子节点的拖放区域 主要元素有dropenter and dropleave事件 但是 如果您将文件拖动到主元素内部和子节点上方 则dropleave被触发 如何处理 以便dropleave仅当拖动的元素和鼠标位于主元素之外时
  • IE7 问题 - 当禁用文件下载自动提示时无法下载流式文件

    我的应用程序是基于 J2EE JSP Servlet 的 当我尝试从 JSP 打开新窗口 弹出窗口 并调用 Servlet 操作 例如 Streamer do 以在该弹出窗口内传输 PDF 文件时 我遇到了问题 问题 当 IE 7 gt 工
  • 从另一台服务器读取 Node.js 中的大文件

    我有两台相互通信的服务器 Server1 向 Server2 请求文件的部分内容 并将收到的数据存储到一个文件中 Server2 应该接收每个请求并创建一个流管道传输数据 假设服务器2中存储的文件 目录 如下 bigfile gz bigf
  • 查看元素的所有 dom 事件

    我有一个 jQuery UI 日期选择器 当您单击日期时 它会清除我的 URL 哈希值 并且不会更改文本框中的日期 我假设某个地方还有其他一些 JavaScript 实用程序 它也正在调用某种委托事件 抛出错误并终止 jquery 处理程序
  • 如何在jsp页面中包含javascript

    我是 J2EE 和 Web 开发的新手 这是我的问题 我想在网页中包含 angular js 这是有效的版本 但我也想要一些本地的 javascript 文件 并且希望我想在本地目录中导入 angularjs
  • 在 Javascript 中动态创建 []array

    也许这将是一个真正愚蠢的问题 但我是 JavaScript 新手 并且坚持动态创建数组 如下格式 items Date 2012 01 21T23 45 10 280Z Value 7 Date 2012 01 26T23 45 10 28

随机推荐

  • cookies,sessionStorage 和 localStorage

    面试问题 如何实现浏览器内多个标签页之间的通信 既请描述一下 cookies sessionStorage 和 localStorage 的区别 cookie在浏览器和服务器间来回传递 sessionStorage和localStorage
  • linux创建线程失败errno=11

    问 题 为什么一个进程调用pthread create来创建线程 当251次就失败了 失败errno11 Resource temporarily unavailable 原 因 一个进程最多拥有250个线程资源 由于pthread cre
  • linux 命令 显示 但是不执行

    用 p命令答应以前的某条命令但是不执行 123 p
  • 026:vue中el-progress逆向倒计时方式显示

    第026个 查看专栏目录 VUE element UI 专栏目标 在vue和element UI联合技术栈的操控下 本专栏提供行之有效的源代码示例和信息点介绍 做到灵活运用 1 提供vue2的一些基本操作 安装 引用 模板使用 comput
  • Excel百万级数据导入导出,EasyExcel 才是真香

    在项目开发中往往需要使用到数据的导入和导出 导入就是从Excel中导入到DB中 而导出就是从DB中查询数据然后使用POI写到Excel上 大数据的导入和导出 相信大家在日常的开发 面试中都会遇到 很多问题只要这一次解决了 总给复盘记录 后期
  • Json与JavaBean之间的转换

    说到json与javaBean之间的转换 这两者更加频繁 json本身就是作为数据交换格式而存在的 在项目中用到的地方很多 这里我只说最常见的一处位置 那就是将数据转换成json再存储到redis中 redis作为缓存数据库 在电商项目中是
  • 物联网全称_物联网的魔力世界

    物联网顾名思义就是一种万物相连的网 英文全称 Internet of Things 缩写IoT 物联网可以让所有能行使独立功能的物体实现相互连接 通过物联网技术 可以用中心计算机对机器 设备或人员进行集中管理 控制 也可以对家用电器 汽车等
  • 构建 react应用程序 (二)(react-scripts实现原理)

    在前面讲到了使用create react app来创建项目 这节我们来分析下原理 react scripts有以下支持 都帮你配置好了 React JSX ES6 and Flow syntax support Language extra
  • xShell操作Linux的常用命令

    我们需要在本地连接Linux服务器 可以用winscp来进行连接 优点是图形化界面 文件的层级关系类似于Windows 更容易操作 也可以使用xShell来进行连接 查看和操作文件就需要使用Linux命令 文件的层级关系没有前者直观 但作为
  • 力扣刷题-210.课程表Ⅱ、图的表示方式、BFS

    一 图的基本概念 定义和基本术语 图是由节点以及连接这些节点边组成 无向图 每条边连接的两个节点可以双向访问 有向图 每条边连接的两个节点只能单向访问 出度 有向图的某个节点作为起点的次数和 入度 有向图的某个节点作为终点的次数和 权重 图
  • springMVC 绑定前台穿来的时间类型数据

    当前台传来的数据 对时间类型的数据其实是无法绑定的 解决办法1 DataTimeFormat pattern yyyy MM dd 标注在实体类的时间字段上 解释 这个注解的支持是来自
  • Cmake简介和简单使用方法

    cmake 简介 CMake是一个跨平台的安装 编译 工具 可以用简单的语句来描述所有平台的安装 编译过程 他能够输出各种各样的makefile或者project文件 能测试编译器所支持的C 特性 类似UNIX下的automake CMak
  • 定义字符串

    目录 一 什么是字符串 二 定义字符串的具体格式 三 求字符数组和字符串长度比较 一 什么是字符串 所谓字符串本质上就是以 0 作为结尾的特殊字符数组 二 定义字符串的具体格式 1 char 字符串名称 字符串长度 字符串所含元素 注意点
  • LabView的简单例题,尽量做到一题多解

    Question 1 亮灯 难度 以组合框为输入条件 分别完成亮红灯 亮黄灯 亮绿灯 灯全灭 Question 2 波形图和波形图表的区别 难度 在波形图和波形图表中显示一个sin函数 sin函数没有定性要求 注意 波形图表输入是数字 而波
  • svn 命令行操作

    文章目录 help checkout help svn help update up checkout co checkout checkout co svn co URL username xxx password xxx svn co
  • IMX6学习记录(10)-挂载SD卡,数据掉电存储

    上面是我的微信和QQ群 欢迎新朋友的加入 目前使用的文件系统是打包成镜像文件的 通过UBOOT挂载镜像 在RAM里面运行起来了 这有个问题 数据不会被存储下来 掉电就会丢失 1 挂载SD卡 fdisk l mount dev mmcblk0
  • Java垃圾回收器

    Java垃圾回收器 1 GC分类与性能指标 1 1 垃圾回收器概述 1 2 垃圾回收器分类 1 2 1 按照线程分 1 2 2 按照工作模式分 1 2 3 碎片处理方式分 1 2 4 工作的内存区间分 1 3 评估GC的性能指标 1 4 吞
  • 另一个Kubernetes(k8s)指南

    从头开始学习Kubernetes Photo by Bobby Burch on Unsplash 近年来 Kubernetes k8s 的受欢迎程度激增 如果您要部署许多容器化的应用程序 那么无论在私有云还是公共云环境中 k8无疑都是当前
  • easyx图形库-----贴图技巧之双缓冲消除闪屏(BeginBatchDraw 与 EndBatchDraw)

    目录 前言 案例1 作图时闪屏 案例2 贴图时闪屏 双缓冲解决闪屏问题 原理 前言 学了easyx图形库的朋友们都知道 我们可以在easyx图形库上面画出连续运动的图片 或者通过贴图的方式把每一帧图片连起来达到动态效果 但是我们每次贴完图片
  • 【react从入门到精通】React父子组件通信方式详解(有示例)

    文章目录 人工智能福利文章 前言 React技能树 通过 props 实现父子组件通信 通过 state 实现父子组件通信 通过回调函数实现父子组件通信 使用 React Context 实现组件通信 总结 写在最后 人工智能福利文章 分享
Powered by Hwhale