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

本文涉及的产品
应用实时监控服务-应用监控,每月50GB免费额度
可观测监控 Prometheus 版,每月50GB免费额度
Serverless 应用引擎免费试用套餐包,4320000 CU,有效期3个月
简介: 在React中,父子组件最常用的4种通信方式:- 通过 props 实现父子组件通信- 通过 state 实现父子组件通信- 通过回调函数实现父子组件通信- 使用 React Context 实现组件通信在项目实战过程中,可根据实际情况选择最合适的通信方式。

前言

image.png

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

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


✍创作不易,求关注😄,点赞👍,收藏⭐️

相关文章
|
3月前
|
XML JavaScript 前端开发
React Jsx语法入门
【8月更文挑战第13天】React Jsx语法入门
46 4
|
27天前
|
监控 前端开发 JavaScript
React 静态网站生成工具 Next.js 入门指南
【10月更文挑战第20天】Next.js 是一个基于 React 的服务器端渲染框架,由 Vercel 开发。本文从基础概念出发,逐步探讨 Next.js 的常见问题、易错点及解决方法,并通过具体代码示例进行说明,帮助开发者快速构建高性能的 Web 应用。
67 10
|
1月前
|
前端开发 JavaScript 开发者
探索现代Web前端技术:React框架入门
【10月更文挑战第9天】 探索现代Web前端技术:React框架入门
|
2月前
|
消息中间件 前端开发
React技术栈-组件间通信的2种方式
本文介绍了React技术栈中组件间通信的两种方式:通过props传递数据和使用消息发布(publish)-订阅(subscribe)机制,并通过实例代码展示了如何使用PubSubJS库实现跨组件通信。
58 11
React技术栈-组件间通信的2种方式
|
2月前
|
移动开发 前端开发 JavaScript
构建高效跨平台移动应用:React Native入门指南
【8月更文挑战第47天】在移动开发领域,React Native凭借其跨平台特性和高效的开发模式赢得了开发者的青睐。本文将通过一个简易的待办事项应用实例,带领读者快速入门React Native,并展示如何利用JavaScript和React框架构建具有原生性能的应用。我们将探讨环境配置、界面布局、状态管理和数据流,以及如何打包和发布您的应用。准备好,让我们开始React Native之旅!
71 20
|
2月前
|
前端开发 JavaScript
React技术栈-React UI之ant-design使用入门
关于React技术栈中使用ant-design库的入门教程,包括了创建React应用、搭建开发环境、配置按需加载、编写和运行代码的步骤,以及遇到错误的解决方法。
43 2
React技术栈-React UI之ant-design使用入门
|
2月前
|
前端开发 JavaScript 开发者
Express.js与前端框架的集成:React、Vue和Angular的示例与技巧
本文介绍了如何将简洁灵活的Node.js后端框架Express.js与三大流行前端框架——React、Vue及Angular进行集成,以提升开发效率与代码可维护性。文中提供了详细的示例代码和实用技巧,展示了如何利用Express.js处理路由和静态文件服务,同时在React、Vue和Angular中构建用户界面,帮助开发者快速掌握前后端分离的开发方法,实现高效、灵活的Web应用构建。
58 3
|
2月前
|
XML 存储 前端开发
React 基础入门
【9月更文挑战第1天】本文详细介绍了由Facebook开发的JavaScript库React,涵盖环境搭建、基本概念、常见问题及解决方案。首先,通过安装Node.js、npm和Create React App快速搭建开发环境;接着,讲解了JSX、组件(包括函数和类组件)、state和props等核心概念;最后,针对JSX语法错误、state异步更新及props与state混淆等问题提供了具体的解决方法和示例代码,帮助读者更好地理解和应用React。
35 2
|
2月前
|
存储 前端开发 JavaScript
React非父子组件之间的事件传递
本文介绍了在React中非父子组件之间如何通过事件总线(eventBus)实现事件传递。
29 0
|
3月前
|
JavaScript 前端开发 容器
React基础入门之虚拟dom【一】
【8月更文挑战第14天】React基础入门之虚拟dom
39 0
React基础入门之虚拟dom【一】