React组件通信

news2024/11/25 4:40:25

react因为组件化,使得组件间通信十分的重要。本文就来简单介绍一些常见的react组件间传递的内容。
我将归纳为以下几种关系来详述:父组件与子组件之间子组件与父组件之间发布者与订阅者模式(context)兄弟组件间,redux也是一种组件管理的方法,但是redux状态管理的内容比较多,这里只做简单介绍,之后再另开一篇详述。

父组件向子组件通信

react的数据流是单向的,最常见的就是通过props由父组件向子组件传值。

示例(关键部分有注释):

我们做一个简单的选择商品,然后改变价格的事例。

父组件:
父组件就是两个按钮,用来切换商品的价格,其中引用了子组件。

class Parents extends Component {
   //构造函数
  constructor() {
    super();
    // 设置state
    this.state = {
      price: 0
    };
  }

clickGoods(e) {
    //更新state
    this.setState({
        price: e
    });
}


  // 渲染
  render() {
    let { price } = this.state;
    return (
      <div>
        <button onClick={this.clickGoods1.bind(this)}>goods1</button>
        <button onClick={this.clickGoods2.bind(this)}>goods2</button>
        // 父组件中        <Child price={price} />
      </div>
    );
  }
}

子组件:
子组件中使用props属性接收传递来的数据。

class Child extends Component {
  render() {
  {/*这里从props中拿到*/}
    return <div> price: {this.props.price} </div>;
  }
}

子组件向父组件通信

接下来我们反过来,让子组件向父组件通信。 子组件向父组件通信的基本思路是,父组件向子组件传一个函数,然后通过这个函数的回调,拿到子组件传过来的值。下面是例子,正好和上面是反的,父组件用来显示价格,子组件显示两个按钮,子组件把价格传递给父组件。

示例(关键部分有注释):

父组件

class Parents extends Component {
  constructor() {
    super();
    this.state = {
      price: 0
    };
  }

  getItemPrice(e) {
    this.setState({
      price: e
    });
  }

  render() {
    return (
      <div>
        <div>price: {this.state.price}</div>
        {/* 向子组件中传入一个函数  */}
        <Child getPrice={this.getItemPrice.bind(this)} />
      </div>
    );
  }
}

子组件

class Child extends Component {
  clickGoods(e) {
    // 在此函数中传入值
    this.props.getPrice(e);
  }

  render() {
    return (
      <div>
        <button onClick={this.clickGoods.bind(this, 100)}>goods1</button>
        <button onClick={this.clickGoods.bind(this, 1000)}>goods2</button>
      </div>
    );
  }
}

发布者与订阅者模式(context)

React 的props都是由父组件传递给子组件的,一旦遇到孙组件,就需要一层层的传递下去。而context提供了一种组件之间通讯的新的方式(16.3版本之后),可以共享一些数据,其它的组件都能从context中读取数据(类似于有个数据源,组件可以订阅这个数据源)。

使用方法

React.createContext()方法

我们可以使用createContext来创建一个context,它可以接收一个变量或者对象做为参数(当对象为参数的时候,react使用object.is()去比较,有些影响性能)。这个传入的值做为context的默认值

 const PriceContext = React.createContext('price')

这样就创建了一个Context

Provider组件

Provider就是用来创建数据源的。它是给所有的子组件提供数据源的跟组件。它接受一个value作为props,用来传递值,它会改变context的默认值。一个provider可以包含多个Consumer组件。如果Provider组件嵌套的话,

<PriceContext.Provider value={100}>
</PriceContext.Provider>

Consumer组件

Consumer表示接受数据的组件,它接受一个函数做为子元素。这个函数会接收context传递的值,返回一个react的组件。Consumer组件必须包含在Provider里面。

<PriceContext.Consumer>
    { /*这里是一个函数*/ }
    {
        price => <div>price:{price}</div>
    }
</PriceContext.Consumer>

示例

在这部分我们尝试一下从父组件直接传递到孙组件,不通过子组件(直接从A组件传值到C组件,不经过B组件)。

参考 React面试题详细解答

// 创建Context
const PriceContext = React.createContext('price')
// A组件中
class ClassA extends Component {
  constructor(){
    super()
    this.state={
      price:0
    }
  }
  // 点击按钮事件
  clickGoods(e) {
    this.setState({
      price:e
    })
  }
  render(){
    const { price } = this.state
    return(
      // Provider
      // 把state里price转到Provider的value中
    <PriceContext.Provider value={price}>
        <button onClick={this.clickGoods.bind(this, 100)}>goods1</button>
        <button onClick={this.clickGoods.bind(this, 1000)}>goods2</button>
        <ClassB />
    </PriceContext.Provider>  
    )
  }
}
// 组件B
class ClassB extends Component {
  // 组件B中只是引用了ClassC,没有进行传值的操作
  render(){
    return(
      <div><span>price:</span><span><ClassC /></span></div>
    )
  }
}
// 组件C
class ClassC extends Component {
  render(){    
    return(
      // Consumer,注意Consumer的下面要包含一个函数
      <PriceContext.Consumer>
        {
          price=><span>{price}</span>
        }
      </PriceContext.Consumer>
    )
  }
}

context的总结与理解

一个react app是由很多react组件组成的,有的组件之间是有嵌套关系的,可以形成一条“组件链”。Context可以当做组件的“作用域”[3]。一个根组件,它定义了一个context,它的组件链上的组件都可以访问到provider中定义的变量或对象,如下图所示,这就比较像‘作用域’的概念。context在一些简单的场景下可以替代部分redux的功能。

兄弟组件间通信

兄弟间组件通信,一般的思路就是找一个相同的父组件,这时候既可以用props传递数据,也可以用context的方式来传递数据。
当然也可以用一些全局的机制去实现通信,比如redux等。

小结

本文主要介绍了3种通信的关系父组件与子组件之间子组件与父组件之间发布者与订阅者模式(context),简述了兄弟组件间的通信。主要是介绍两种方式,利用props属性和Context。也介绍了一些context的理解。

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

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

相关文章

Netty入门——基于NIO实现机器客服案例

Netty简单案例前言环境准备前置知识网络传输的几种实现方式BIO——同步阻塞IONIO——同步非阻塞IOAIO——异步非阻塞IO适用范围Netty简介特点核心组件使用场景运行简图案例简介关键代码客户端服务器端运行状况总结前言 最近学完了Netty&#xff0c;在这里关于Netty中实现NIO做…

【Shell 脚本速成】09、Shell 循环控制语句 for

目录 一、循环控制 break 语句 二、循环控制 continue 语句 三、循环控制 sleep 四、参数控制命令-shift 五、脚本退出命令 exit 总结 六、for 嵌套 6.1 for 嵌套 if 七、for 与数组 7.1 使用 for 循环遍历读出数组 7.2 使用 for 循环进行数组存值 一、循环控制 bre…

Zabbix6.0使用教程 (一)—zabbix新增功能介绍2

上一篇我们已经介绍了部分zabbix6.0的新增功能&#xff0c;这期我们将继续为家详细介绍下余下的zabbix6.0新增功能&#xff0c;大家可以往下看。 六、监控项 6.1 自动类型选择 监控项配置表单会自动建议匹配的信息类型&#xff0c;如果选定的监控项键值仅返回特定类型的数据…

迷宫逃离的问题-CoCube

ROS1云课→20迷宫不惑之A*大法&#xff08;一种虽古老但实用全局路径规划算法&#xff09; 将CoCube分别放入如下地图中的左侧&#xff0c;如何从右侧逃离&#xff1a; 需要算法&#xff1a;求解起点到终点的路径。 还需要什么&#xff1f; 参考&#xff1a; &#xff08;eng.…

目标检测算法——垃圾分类数据集汇总(附下载链接)

&#x1f384;&#x1f384;近期&#xff0c;小海带在空闲之余收集整理了一批垃圾分类数据集供大家参考。 整理不易&#xff0c;小伙伴们记得一键三连喔&#xff01;&#xff01;&#xff01;&#x1f388;&#x1f388; 目录 一、Kaggle 垃圾分类图片数据集 二、垃圾分类数据…

全国青少年软件编程等级考试Python标准解读(1_6级)

考核性质&#xff1a; 全国青少年软件编程等级考试标准&#xff08;Python语言&#xff09;由中国电子学会科普培训与应用推广中心和北京大学信息科学技术学院共同制定。由全国青少年电子信息科普创新联盟标准工作组开发&#xff0c;由中国电子学会普及工作委员会审核通过&…

央视主持人康辉再次出圈,一口气播出一个多小时不卡顿、零失误

说起中央电视台的主持人&#xff0c;曾经有好几个国字脸&#xff0c;不过随着时间的流逝&#xff0c;他们都消失在历史的长河里。如今的央视主持人队伍&#xff0c;康辉可以算得上天花板级别的人&#xff0c;他也因此俘获了一大批观众&#xff0c;成为最受欢迎的主持人。 专业科…

阿里P5的测试开发工程师,都有哪些要求?

【北京】高德 高级测试开发工程师&#xff08;面议&#xff09; 职位描述&#xff1a; 1、负责高德信息服务核心服务端系统测试和质量保障体系建设&#xff1b; 2、为复杂高德信息-本地生活系统设计并执行高质量的综合测试方案&#xff1b; 3、通过多种技术手段实现高度自…

数据库常见死锁原因及处理

目录前言什么是死锁死锁产生的四个必要条件1. 表锁死锁死锁场景解决方案建议2. 行锁死锁2.1 两个事务分别想拿到对方持有的锁&#xff0c;互相等待&#xff0c;于是产生死锁死锁场景解决方案2.2 共享锁转换为排他锁死锁场景解决方案3. INSERT ... ON DUPLICATE KEY UPDATE产生d…

[附源码]Python计算机毕业设计Django疫情防控平台

项目运行 环境配置&#xff1a; Pychram社区版 python3.7.7 Mysql5.7 HBuilderXlist pipNavicat11Djangonodejs。 项目技术&#xff1a; django python Vue 等等组成&#xff0c;B/S模式 pychram管理等等。 环境需要 1.运行环境&#xff1a;最好是python3.7.7&#xff0c;…

Watch事件介绍_java培训

Watch事件 Java培训课程 Watch事件 一次触发 当数据有了变化时zkserver向客户端发送一个watch,它是一次性的动作&#xff0c;即触发一次就不再有效&#xff0c;类似一次性纸杯。 只监控一次。如果想继续Watch的话&#xff0c;需要客户端重新设置Watcher。因此如果你得到一个w…

【Android Studio程序开发】按钮触控---按钮控件Button

除了文本视图之外&#xff0c;按钮Button也是一种基础控件。因为Button是由TextView派生而来&#xff0c;所以文本视图 拥有的属性和方法&#xff0c;包括文本内容、文本大小、文本颜色等&#xff0c;按钮控件均能使用。不同的是&#xff0c;Button拥有默认的按钮背景&#xff…

采购管理系统有什么用,哪个好?

如今随着各行各业的采购组织管理理念的不断变换&#xff0c;利用信息化手段来管理企业采购行为已然成为一种趋势。 现代采购管理系统可以使采购组织规范采购工作的组织实施&#xff0c;建立有责任感的管理体系&#xff0c;从而提高企业经济效益和采购质量&#xff0c;增强企业…

Linux搭建 FTP服务器

Linux搭建 FTP服务器 vsftpd 是 very secure ftp daemon 的缩写&#xff0c;它是 Linux 上使用最受欢迎、使用最广泛的 FTP 服务器之一&#xff0c;它具有安全&#xff0c;速度快&#xff0c;稳定的特点&#xff0c;很多重要的 FTP 站点比如 ftp.gnu.org、ftp.freebsd.org 都是…

【JavaWeb开发-Servlet】day03-URL参数传递与MySQL数据库连接

目录 1、登录示例&#xff0c;谁用url传递参数 &#xff08;1&#xff09;创建一个Servlet类&#xff0c;名字叫做loginServlet &#xff08;2&#xff09;保留需要的部分 &#xff08;3&#xff09;删除多余代码 &#xff08;4&#xff09;编写loginServlet.class &#xff08…

ICV:2022年中国车载摄像头市场规模有望突破50亿美元大关

全球前沿科技咨询机构ICV近期发布了全球车载摄像头的市场分析报告。ICV在报告中指出&#xff0c;车载摄像头市场随着乘用车自动驾驶的发展呈现出快速增长的趋势&#xff0c;2022年中国市场在全球范围内仍保持“市场领跑者”的地位&#xff0c;并有望突破50亿美元市场规模的大关…

Win10如何安装JDK1.8,最快最详细教程

JDK全称为Java Development Kit&#xff0c;顾名思义是java开发工具包&#xff0c;是程序员使用java语言编写java程序所需的开发工具包。 JRE全称为Java Runtime Environment&#xff0c;顾名思义是java运行时的环境&#xff0c;包含了java虚拟机&#xff0c;java基础类库&…

ABAP-SAP-整合事务码,整合平台,运维工具箱

PROCESS BEFORE OUTPUT. MODULE status_0100. * PROCESS AFTER INPUT. MODULE user_command_0100. MODULE exit_command_0100 AT EXIT-COMMAND. 源码&#xff1a; **Project Name : SAP Implementation Project **Program Name : ZTOOL **Description : 运维工具箱 **Date/Aut…

比羊了个羊还火的ChatGPT,玩法全攻略讲解

大家好&#xff0c;我是洋子&#xff0c;昨天听闻了ChatGPT&#xff0c;真的非常强大&#xff0c;赶紧给大家安利一波 ChatGPT是一种由OpenAI开发的通用聊天机器人模型 该模型是基于GPT-3&#xff08;一种大型语言模型&#xff09;构建的&#xff0c;旨在提供与人类更加自然的…

Pig4Cloud之登陆验证(二)发放token

上一篇介绍了客户端认证处理&#xff0c;那是令牌颁发的前提。这篇开始&#xff0c;我们就来研究下令牌颁发。 令牌颁发 授权服务器提供令牌颁发接口&#xff08;/oauth2/token&#xff09;&#xff0c;由客户端发起请求&#xff0c;授权服务器生成访问令牌&#xff08;acces…