目录
一、父子组件通信
二、跨级组件通信
三、兄弟(无嵌套)组件通信
四、路由传值
五、Redux
首页 web前端 js教程 简单常用技巧之React组件间通信(整理分享)

简单常用技巧之React组件间通信(整理分享)

Jan 28, 2022 pm 05:30 PM
react

本篇文章给大家带来了React组件间通信简单易用的常用方式,React知识中一个主要内容便是组件之间的通信,以下列举几种常用的组件通信方式,结合实例,通俗易懂,建议收藏,希望对大家有帮助。

简单常用技巧之React组件间通信(整理分享)

一、父子组件通信

原理:父组件通过props(与vue中的props区分开)向子组件通信,子组件通过回调事件与父组件通信。

首先,先创建一个父组件Parent.js跟子组件Children.js,二者的关系为直接父子关系。

Parent.js父组件如下,给父组件一个默认状态state,引入子组件,通过在子组件加上toChildren={this.state.msg},该处即为向子组件传props。

import React from 'react';
import { Button } from 'element-react';
import Children from './Children';

class Parent extends React.Component {
  constructor(props) {
	super(props);
	this.state = {
		msg:'父组件传递给子组件'
	};
    this.changeMsg = this.changeMsg.bind(this)
  }
  changeMsg(){
    this.setState({
      msg:'父组件传递给子组件(改变之后的内容)'
    })
  }
  render(){
    return (
      <p style={{backgroundColor:&#39;#f7ba2a&#39;,padding:&#39;20px&#39;,width:&#39;500px&#39;,margin:&#39;auto&#39;,textAlign:&#39;center&#39;}}>
        <p>父子组件通信实例</p>
        <Button onClick={this.changeMsg}>父传子</Button>
        <Children toChildren={this.state.msg}></Children>
      </p>
    )
  }
}

export default Parent
登录后复制

Children.js子组件如下,初始状态通过props拿到父组件传过来的值。

import React from 'react';

class Children extends React.Component {
  constructor(props) {
	super(props);
	this.state = {
		msg:this.props.toChildren   //通过props拿到父组件传过来的值
	};
  }
  render(){
    return (
      <p style={{backgroundColor:&#39;#13ce66&#39;,padding:&#39;10px&#39;,width:&#39;200px&#39;,margin:&#39;auto&#39;,marginTop:&#39;20px&#39;}}>
        <p>从父组件传过来:</p>
        <span style={{color:&#39;blue&#39;}}>{this.state.msg}</span>
      </p>
    )
  }
}

export default Children
登录后复制

注意:子组件取值时应与父组件放在子组件的字段props一致,即本例中的 toChildren,如下

 那么子组件想向父组件传值(向上传值),可以通过调用父组件传过来的回调函数

在Parent.js中向Children.js中加入回调函数callback,绑定changeMsg方法

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

class Parent extends React.Component {
  constructor(props) {
	super(props);
	this.state = {
	    msg:'父组件传递给子组件',
        fromChildrn:''
	};
    this.changeMsg = this.changeMsg.bind(this)
  }
  changeMsg(val){
    this.setState({
      fromChildrn: val
    })
  }
  render(){
    return (
      <p style={{backgroundColor:&#39;#f7ba2a&#39;,padding:&#39;20px&#39;,width:&#39;500px&#39;,margin:&#39;auto&#39;,textAlign:&#39;center&#39;}}>
        <p>父子组件通信实例</p>
        <span style={{color:&#39;red&#39;}}>{this.state.fromChildrn}</span>
        <Children toChildren={this.state.msg} callback={this.changeMsg}></Children>
      </p>
    )
  }
}

export default Parent
登录后复制

在子组件中,用this.props.callback()执行父组件的回调函数,从而执行绑定方法changeMsg,显示子组件传过来的值

import React from 'react';
import { Button } from 'element-react';

class Children extends React.Component {
  constructor(props) {
	super(props);
	this.state = {
		msg:this.props.toChildren
	};
    this.toParent = this.toParent.bind(this)
  }
  toParent(){
    this.props.callback('子组件传过来的值')   //子组件通过此触发父组件的回调方法
  }
  render(){
    return (
      <p style={{backgroundColor:&#39;#13ce66&#39;,padding:&#39;10px&#39;,width:&#39;200px&#39;,margin:&#39;auto&#39;,marginTop:&#39;20px&#39;}}>
        <p>从父组件传过来:</p>
        <span style={{color:&#39;blue&#39;}}>{this.state.msg}</span>
        <Button onClick={this.toParent}>子传父</Button>
      </p>
    )
  }
}

export default Children
登录后复制

注意:props中的回调函数名称需一致,即本例中的callback,如下

小结: 以上为直接父子组件通信的其中一种方式,父传子,通过props;子传父,执行回调。

二、跨级组件通信

假设一个父组件中存在一个子组件,这个子组件中又存在一个子组件,暂且称为“孙组件”,当父组件需要与“孙组件”通信时,常用的方式有两种,逐层传值与跨层传值。

1、逐层传值

这种方式就是上面的直接父子通信的基础上在加上一个中间层。如父、“孙”组件通信,可以先父子通信,然后再子“孙”通信,传递的层级变成父-->子-->“孙”,同理,通过props往下传,通过回调往上传。不展开,有兴趣的自己动手实现一下。

2、跨级传值

顾名思义,父跟“孙”通信,不需要经过子(中间层)组件。这里引出了Context

React官方文档对Context做出了解释:

在一个典型的 React 应用中,数据是通过 props 属性自上而下(由父及子)进行传递的,但这种做法对于某些类型的属性而言是极其繁琐的(例如:地区偏好,UI 主题),这些属性是应用程序中许多组件都需要的。Context 提供了一种在组件之间共享此类值的方式,而不必显式地通过组件树的逐层传递 props。

一句话概括就是:跨级传值,状态共享

看下简单的实例,直接讲用法。

首先,我先创建一个context.js文件(与父子孙同个目录),默认值为一个对象。

import React from "react";
const MyContext = React.createContext({text:'luck'});
export default MyContext
登录后复制

然后,对父组件进行改写,引入context,使用一个 Provider 来将当前的 value 传递给以下的组件树,value为传递的值。

import React from 'react';
import Children from './Children';
import MyContext from './context';

class Parent extends React.Component {
  constructor(props) {
	super(props);
  }
  // 使用一个 Provider 来将当前的 value 传递给以下的组件树。
  // 无论多深,任何组件都能读取这个值。
  render(){
    return (
      <p style={{backgroundColor:&#39;#f7ba2a&#39;,padding:&#39;20px&#39;,width:&#39;500px&#39;,margin:&#39;auto&#39;,textAlign:&#39;center&#39;}}>
        <p>context通信实例</p>
        <MyContext.Provider value={{text:&#39;good luck&#39;}}>
          <Children></Children>
        </MyContext.Provider>
      </p>
    )
  }
}

export default Parent
登录后复制

子组件为中间层,不做处理,用于包裹“孙”组件。

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

class Children extends React.Component {
  render(){
    return (
      <p>
        <Grandson></Grandson>
      </p>
    )
  }
}

export default Children
登录后复制

新增一个“孙”组件,同样需引入context,在组件内部添加static contextType = MyContext,此时将能通过this.context直接获取到上层距离最近的Provider传递的值,此时this.context = {text:good luck},即父组件传递value。

import React from 'react';
import MyContext from './context';

class Grandson extends React.Component {
  static contextType = MyContext
  render(){
    return (
      <p style={{backgroundColor:&#39;#13ce66&#39;,padding:&#39;10px&#39;,width:&#39;200px&#39;,margin:&#39;auto&#39;,marginTop:&#39;20px&#39;}}>
        <p>通过context传过来:</p>
        <span style={{color:&#39;blue&#39;}}>{this.context.text}</span>
      </p>
    )
  }
}

export default Grandson
登录后复制

通过this.context.text获取到传递的值。

 以上的是一个父-->孙的过程,即向下的流程,如果想孙-->父向上传值,可以通过回调的方式

对父组件进行传值修改,在传过来的对象中添加一个属性,里面绑定父组件的方法value={{text:'good luck',toParent:this.fromGranson}}

import React from 'react';
import Children from './Children';
import MyContext from './context';

class Parent extends React.Component {
  constructor(props) {
	super(props);
    this.state = {
      msg:''
    };
    this.fromGranson = this.fromGranson.bind(this)
  }
  fromGranson(val){
    this.setState({
      msg:val
    })
  }
  // 使用一个 Provider 来将当前的 theme 传递给以下的组件树。
  // 无论多深,任何组件都能读取这个值。
  render(){
    return (
      <p style={{backgroundColor:&#39;#f7ba2a&#39;,padding:&#39;20px&#39;,width:&#39;500px&#39;,margin:&#39;auto&#39;,textAlign:&#39;center&#39;}}>
        <p>context通信实例</p>
        <span style={{color:&#39;red&#39;}}>{this.state.msg}</span>
        <MyContext.Provider value={{text:&#39;good luck&#39;,toParent:this.fromGranson}}>
          <Children></Children>
        </MyContext.Provider>
      </p>
    )
  }
}

export default Parent
登录后复制

然后在孙组件中添加一个按钮,绑定方法,执行函数回调

toParent(){
    this.context.toParent('孙组件向父组件传数据')
 }

import React from 'react';
import MyContext from './context';
import { Button } from 'element-react'

class Grandson extends React.Component {
  static contextType = MyContext
  constructor(props) {
		super(props);
    this.toParent = this.toParent.bind(this)
	}
  toParent(){
    this.context.toParent('孙组件向父组件传数据')
  }
  render(){
    return (
      <p style={{backgroundColor:&#39;#13ce66&#39;,padding:&#39;10px&#39;,width:&#39;200px&#39;,margin:&#39;auto&#39;,marginTop:&#39;20px&#39;}}>
        <p>通过context传过来:</p>
        <span style={{color:&#39;blue&#39;}}>{this.context.text}</span>
        <p><Button onClick={this.toParent}>context向上</Button></p>
      </p>
    )
  }
}

export default Grandson
登录后复制

默认的页面为:

 点击按钮之后,执行context中的回调,向上传值。

 不管层级有多深,都可以使用context进行向下或向上传值。

注意:在下层组件中取的context中的字段需与value中传递字段保持一致。text与toParent

 

以上就是Context的大致使用,更多细节请往React官方文档:

Context – React=https://react.docschina.org/docs/context.html

三、兄弟(无嵌套)组件通信

当两个组件互不嵌套,处在同个层级或者不同层级上,他们之间要进行通信,有以下几种常用方法

1、某个组件先将值传到同一个父组件,然后在通过父组件传给另外一个组件,用到父子组件传值

2、使用缓存sessionStorage、localStorage等

3、如果两个组件之间存在跳转,可以使用路由跳转传值,附上详细用法

React学习笔记 -- 组件通信之路由传参(react-router-dom)_前端菜小白leo的博客-CSDN博客

4、event(发布--订阅)

首先,安装event

npm install event -save
登录后复制

新建一个event.js

import { EventEmitter } from 'events';
export default new EventEmitter();
登录后复制

然后另两个组件处于同层级(不同个父组件或者不同层级都可以)

import React from 'react';
import Grandson from './Grandson';
import GrandsonOther from './GrandsonOther';

class Children extends React.Component {
  render(){
    return (
      <p>
        <Grandson></Grandson>
        <GrandsonOther></GrandsonOther>
      </p>
    )
  }
}

export default Children
登录后复制

组件一,导入event,在componentDidMount阶段添加监听addListener(订阅),在componentWillUnmount移除监听removeListener,事件名称与组件二中emit一致。

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

class Grandson extends React.Component {
  constructor(props) {
	super(props);
    this.state = {
      msg:''
    }
  }
  componentDidMount(){
    event.addListener('eventMsg',val => {
      this.setState({
        msg:val
      })
    })
  }
  componentWillUnmount(){
    event.removeListener('eventMsg')
  }
  render(){
    return (
      <p style={{backgroundColor:&#39;#13ce66&#39;,padding:&#39;10px&#39;,width:&#39;200px&#39;,margin:&#39;auto&#39;,marginTop:&#39;20px&#39;}}>
        <p>组件一</p>
        <p>通过event传过来:</p>
        <span style={{color:&#39;red&#39;}}>{this.state.msg}</span>
      </p>
    )
  }
}

export default Grandson
登录后复制

组件二,导入event,按钮绑定方法,使用event.emit触发(发布)事件。

import React from 'react';
import event from '../event';
import { Button } from 'element-react'

class Grandson extends React.Component {
  constructor(props) {
	super(props);
    this.state = {
      msg:''
    }
    this.toOther = this.toOther.bind(this)
  }
  toOther(){
    event.emit('eventMsg','通过evnet传过来的值')
  }
  render(){
    return (
      <p style={{backgroundColor:&#39;#13ce66&#39;,padding:&#39;10px&#39;,width:&#39;200px&#39;,margin:&#39;auto&#39;,marginTop:&#39;20px&#39;}}>
        <p>组件二</p>
        <span style={{color:&#39;blue&#39;}}>{this.state.msg}</span>
        <p><Button onClick={this.toOther}>event传值</Button></p>
      </p>
    )
  }
}

export default Grandson
登录后复制

点击按钮,组件二发布事件,组件一监听(订阅)事件,更新内容。(如果交换发布者订阅者身份,写法一致)

注意:如果两个组件使用event进行通信,确保发布订阅的事件名称一致,如上例中 eventMsg

小结: event的方式比较灵活,不管是父子、跨级、还是同级,甚至毫无关联的组件,都可以使用此方式进行通信。

四、路由传值

React学习笔记 -- 组件通信之路由传参(react-router-dom)_前端菜小白leo的博客-CSDN博客

五、Redux

Redux基本用法(在react中使用,链路打通)_前端菜小白leo的博客-CSDN博客

总结:主要讲了react中常用的组件通信方式,在平时工作中,根据不同的应用场景,选择不同的通信方式,会让通信流程更加简单、清晰。

对比Vue中的组件通信方式,你会发现很多相似之处:

Vue组件间的通信方式(多种场景,通俗易懂,建议收藏)_前端菜小白leo的博客-CSDN博客

推荐学习:《react视频教程

以上是简单常用技巧之React组件间通信(整理分享)的详细内容。更多信息请关注PHP中文网其他相关文章!

本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

Video Face Swap

Video Face Swap

使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热工具

记事本++7.3.1

记事本++7.3.1

好用且免费的代码编辑器

SublimeText3汉化版

SublimeText3汉化版

中文版,非常好用

禅工作室 13.0.1

禅工作室 13.0.1

功能强大的PHP集成开发环境

Dreamweaver CS6

Dreamweaver CS6

视觉化网页开发工具

SublimeText3 Mac版

SublimeText3 Mac版

神级代码编辑软件(SublimeText3)

React前后端分离指南:如何实现前后端的解耦和独立部署 React前后端分离指南:如何实现前后端的解耦和独立部署 Sep 28, 2023 am 10:48 AM

React前后端分离指南:如何实现前后端的解耦和独立部署,需要具体代码示例在当今的Web开发环境中,前后端分离已经成为一种趋势。通过将前端和后端代码分开,可以使得开发工作更加灵活、高效,并且方便进行团队协作。本文将介绍如何使用React实现前后端分离,从而实现解耦和独立部署的目标。首先,我们需要理解什么是前后端分离。传统的Web开发模式中,前端和后端是耦合在

如何利用React和RabbitMQ构建可靠的消息传递应用 如何利用React和RabbitMQ构建可靠的消息传递应用 Sep 28, 2023 pm 08:24 PM

如何利用React和RabbitMQ构建可靠的消息传递应用引言:现代化的应用程序需要支持可靠的消息传递,以实现实时更新和数据同步等功能。React是一种流行的JavaScript库,用于构建用户界面,而RabbitMQ是一种可靠的消息传递中间件。本文将介绍如何结合React和RabbitMQ构建可靠的消息传递应用,并提供具体的代码示例。RabbitMQ概述:

React Router使用指南:如何实现前端路由控制 React Router使用指南:如何实现前端路由控制 Sep 29, 2023 pm 05:45 PM

ReactRouter使用指南:如何实现前端路由控制随着单页应用的流行,前端路由成为了一个不可忽视的重要部分。ReactRouter作为React生态系统中最受欢迎的路由库,提供了丰富的功能和易用的API,使得前端路由的实现变得非常简单和灵活。本文将介绍ReactRouter的使用方法,并提供一些具体的代码示例。安装ReactRouter首先,我们需

PHP、Vue和React:如何选择最适合的前端框架? PHP、Vue和React:如何选择最适合的前端框架? Mar 15, 2024 pm 05:48 PM

PHP、Vue和React:如何选择最适合的前端框架?随着互联网技术的不断发展,前端框架在Web开发中起着至关重要的作用。PHP、Vue和React作为三种具有代表性的前端框架,每一种都具有其独特的特点和优势。在选择使用哪种前端框架时,开发人员需要根据项目需求、团队技能和个人偏好做出明智的决策。本文将通过比较PHP、Vue和React这三种前端框架的特点和使

Java框架与前端React框架的整合 Java框架与前端React框架的整合 Jun 01, 2024 pm 03:16 PM

Java框架与React框架的整合:步骤:设置后端Java框架。创建项目结构。配置构建工具。创建React应用。编写RESTAPI端点。配置通信机制。实战案例(SpringBoot+React):Java代码:定义RESTfulAPI控制器。React代码:获取并显示API返回的数据。

如何利用React开发一个响应式的后台管理系统 如何利用React开发一个响应式的后台管理系统 Sep 28, 2023 pm 04:55 PM

如何利用React开发一个响应式的后台管理系统随着互联网的快速发展,越来越多的企业和组织需要一个高效、灵活、易于管理的后台管理系统来处理日常的操作事务。React作为目前最受欢迎的JavaScript库之一,提供了一种简洁、高效和可维护的方式来构建用户界面。本文将介绍如何利用React开发一个响应式的后台管理系统,并给出具体的代码示例。创建React项目首先

vue.js vs.反应:特定于项目的考虑因素 vue.js vs.反应:特定于项目的考虑因素 Apr 09, 2025 am 12:01 AM

Vue.js适合中小型项目和快速迭代,React适用于大型复杂应用。1)Vue.js易于上手,适用于团队经验不足或项目规模较小的情况。2)React的生态系统更丰富,适合有高性能需求和复杂功能需求的项目。

react有哪些闭包 react有哪些闭包 Oct 27, 2023 pm 03:11 PM

react有事件处理函数、useEffect和useCallback、高阶组件等等闭包。详细介绍:1、事件处理函数闭包:在React中,当我们在组件中定义一个事件处理函数时,该函数会形成一个闭包,可以访问组件作用域内的状态和属性。这样可以在事件处理函数中使用组件的状态和属性,实现交互逻辑;2、useEffect和useCallback中的闭包等等。

See all articles