React 组件间通信方式简介


React 组件间通信主要分为以下四种情况:

  • 父组件向子组件通信
  • 子组件向父组件通信
  • 跨级组件之间通信
  • 非嵌套组件间通信

下面对这四种情况分别进行介绍:

 

父组件向子组件通信

父组件通过 props 和子组件进行通信,子组件得到 props 后进行相应的操作 
父组件 App.js:

 
  1. import React, { Component } from 'react';
  2. import './App.css';
  3. import Child1 from './Child1';
  4. class App extends Component {
  5. render() {
  6. return (
  7. <div className="App">
  8. <Child1 content="父组件传递的内容" />
  9. </div>
  10. );
  11. }
  12. }
  13. export default App;

子组件 Child1.jsx

 
  1. import React, { Component } from 'react';
  2. class Child1 extends Component {
  3. render () {
  4. return (
  5. <div>
  6. 子组件一:{ this.props.content }
  7. </div>
  8. )
  9. }
  10. }
  11. export default Child1;
 

子组件向父组件通信

和父组件向子组件通信类似,父组件通过传递 props 给子组件,只不过 props 的内容是一个函数,子组件通过调用父组件传递过来的回调函数,将子组件内容传递给父组件。 
父组件 App.js

 
  1. import React, { Component } from 'react';
  2. import logo from './logo.svg';
  3. import './App.css';
  4. import Child1 from './Child1';
  5. import Child2 from './Child2';
  6. class App extends Component {
  7. constructor(){
  8. super();
  9. this.state = {
  10. msg:'',
  11. }
  12. }
  13. childMsg(msg){
  14. this.setState({
  15. msg: msg,
  16. })
  17. }
  18. render() {
  19. return (
  20. <div className="App">
  21. 子组件二传过来的内容:{this.state.msg}
  22. <Child2 childMsg={this.childMsg.bind(this)}/>
  23. </div>
  24. );
  25. }
  26. }
  27. export default App;

子组件 Child2.jsx:

 
  1. import React, { Component } from 'react';
  2. class Child2 extends Component {
  3. msgHandle(){
  4. this.props.childMsg(this.refs.input.value);
  5. }
  6. render () {
  7. return (
  8. <div>
  9. 子组件二:
  10. <input type="text" placeholder='请输入内容' ref='input' />
  11. <button onClick={this.msgHandle.bind(this)}>点击向父组件传参</button>
  12. </div>
  13. )
  14. }
  15. }
  16. export default Child2;
 

跨级组件通信

跨级组件是指父组件向子组件的子组件进行通信,或者向更深层次的子组件通信,主要有两种方式:

  • 通过 props 层层传递
  • 使用 context 对象

对于层级不深的组件(三层以内),可以使用 props 进行层层传递,如果说层级更深的话, 
每一层组件都要去传递 props,并且这些 props 可能不是自身需要的,这就增加了复杂度,这种场景就可以使用 context 进行通信。context 是一个全局变量,相当于一个大容器,我们把要传递的信息放到这个容器里面,不管嵌套层级多深,子组件都可以获取到信息。使用 context 需要满足以下三个条件: 
1、父组件需要声明自己支持 context,并提供 context 对象中属性的 PropTypes 
2、子组件需要声明自己需要使用 context,并提供其需要使用的 context 属性的 PropTypes。 
3、父组件需要提供一个 getChildContext 函数,用来返回一个初始的 context 对象

props 层层传递: 
父组件App.js:

 
  1. import React, { Component } from 'react';
  2. import logo from './logo.svg';
  3. import './App.css';
  4. import Child1 from './Child1';
  5. class App extends Component {
  6. constructor(){
  7. super();
  8. }
  9. render() {
  10. return (
  11. <div className="App">
  12. <Child1 content="父组件传递给孙子组件的内容" />
  13. </div>
  14. );
  15. }
  16. }
  17. export default App;

Child1.jsx:

 
  1. import React, { Component } from 'react';
  2. import Child1_1 from './Child1_1';
  3. class Child1 extends Component {
  4. render () {
  5. return (
  6. <div>
  7. <Child1_1 content={this.props.content}/>
  8. </div>
  9. )
  10. }
  11. }
  12. export default Child1;

Child1_1.jsx:

 
  1. import React, { Component } from 'react';
  2. class Child1_1 extends Component {
  3. render () {
  4. return (
  5. <div>
  6. 子组件一的子组件:{ this.props.content }
  7. </div>
  8. )
  9. }
  10. }
  11. export default Child1_1;

context 对象传递 
父组件App.js:

 
  1. import React, { Component } from 'react';
  2. import logo from './logo.svg';
  3. import './App.css';
  4. import PropTypes from "prop-types";
  5. import Child1 from './Child1';
  6. class App extends Component {
  7. // 声明支持 context
  8. static childContextTypes = {
  9. msgs: PropTypes.string,
  10. callBack: PropTypes.func,
  11. }
  12. // 父组件提供一个函数,返回初始的 context 对象
  13. getChildContext(){
  14. return {
  15. msgs:'父组件传递的初始内容',
  16. callBack:this.callBack
  17. }
  18. }
  19. callBack(msgs){
  20. console.log(msgs);
  21. }
  22. render() {
  23. return (
  24. <div className="App">
  25. <Child1 />
  26. </div>
  27. );
  28. }
  29. }
  30. export default App;

子组件 Child1.jsx:

 
  1. import React, { Component } from 'react';
  2. import Child12 from './Child1_2';
  3. class Child1 extends Component {
  4. render () {
  5. return (
  6. <div>
  7. <Child12 />
  8. </div>
  9. )
  10. }
  11. }
  12. export default Child1;

子组件的子组件 Child1_2:

 
  1. import React, { Component } from 'react';
  2. import PropTypes from 'prop-types';
  3. class Child1_2 extends Component {
  4. // 子组件声明需要调动 context
  5. static contextTypes = {
  6. msgs:PropTypes.string,
  7. callBack:PropTypes.func
  8. }
  9. callBack(){
  10. this.context.callBack('孙子组件的信息');
  11. }
  12. render () {
  13. return (
  14. <div>
  15. 子组件一的子组件:{ this.context.msgs }
  16. <button onClick={this.callBack.bind(this)}>点击给爷爷组件传递信息</button>
  17. </div>
  18. )
  19. }
  20. }
  21. export default Child1_2;
 

非嵌套组件间通信

表示没有任何包含关系的组件,主要包括兄弟组件和不在同一个父级中的非兄弟组件。

  • 使用共同父组件的 context 对象通信
  • 使用自定义事件的方式

对于使用共同父组件 context 的方式会增加子组件和父组件之间的耦合度,对于层级较深的组件找到共同父组件也比较麻烦,但是这种方式可实施。

为了避免父子组件之间的耦合度,我们采用自定义事件的方式: 
需要安装 events 包,使用该模块的自定义事件机制npm i events --save 
在根目录下新建 events.js 文件:

 
  1. import { EventEmitter } from 'events';
  2. export default new EventEmitter();

父组件 App.js:

 
  1. import React, { Component } from 'react';
  2. import logo from './logo.svg';
  3. import './App.css';
  4. import Child1 from './Child1';
  5. import Child2 from './Child2';
  6. class App extends Component {
  7. render() {
  8. return (
  9. <div className="App">
  10. <Child1 />
  11. <Child2 />
  12. </div>
  13. );
  14. }
  15. }
  16. export default App;

子组件 Child1.jsx:

 
  1. import React, { Component } from 'react';
  2. import emitter from './events';
  3. class Child1 extends Component {
  4. constructor(props){
  5. super(props);
  6. this.state = {
  7. msg:''
  8. }
  9. }
  10. // 组件挂载完后,声明一个自定义事件
  11. componentDidMount(){
  12. this.eventEmitter = emitter.addListener('selfEventName',msg => {
  13. this.setState({
  14. msg: msg
  15. })
  16. })
  17. }
  18. // 组件销毁前清除事件监听
  19. componentWillUnmount(){
  20. emitter.removeListener(this.eventEmitter)
  21. }
  22. render () {
  23. return (
  24. <div>
  25. 子组件二传递过来的内容:{ this.state.msg }
  26. </div>
  27. )
  28. }
  29. }
  30. export default Child1;

子组件 Child2.jsx:

 
    1. import React, { Component } from 'react';
    2. import emitter from './events';
    3. class Child2 extends Component {
    4. msgHandle(){
    5. emitter.emit('selfEventName','自定义事件传参');
    6. }
    7. render () {
    8. return (
    9. <div>
    10. 子组件二:
    11. <button onClick={this.msgHandle.bind(this)}>点击向父组件传参</button>
    12. </div>
    13. )
    14. }
    15. }
    16. export default Child2;

React 组件间通信介绍的更多相关文章

  1. vue 和 react 组件间通信方法对比

    vue 和 react 组件间通信方法对比: 通信路径 vue的方法 react的方法 父组件 => 子组件 props(推荐).slot(推荐).this.$refs.this.$childr ...

  2. React组件间通信-sub/pub机制

    React生命周期第二个demo演示了兄弟组件的通信,需要通过父组件,比较麻烦:下面介绍sub/pub机制来事项组件间通信. 1.导包 npm i pubsub-js 2.UserSearch.jsx ...

  3. React 组件间通信 总结

    组件间通信 5.1.1. 方式一: 通过props传递 1)         共同的数据放在父组件上, 特有的数据放在自己组件内部(state) 2)         通过props可以传递一般数据和 ...

  4. React组件间通信

    众所周知,ReactJS组件与组件之间的通信是一个难点.在React实际开发中,父子组件之间的传值是比较常见的,刚入门的小伙伴很容易被组件之间的通信绕懵. 今天花了点时间总结了一下React父子组件之 ...

  5. react 组件间通信,父子间通信

    一.父组件传值给子组件 父组件向下传值是使用了props属性,在父组件定义的子组件上定义传给子组件的名字和值,然后在子组件通过this.props.xxx调用就可以了. 二.子组件传值给父组件 子组件 ...

  6. React 组件间通信

    https://jsfiddle.net/69z2wepo/9719/ <script src="https://facebook.github.io/react/js/jsfiddl ...

  7. React独立组件间通信联动

    React是现在主流的高效的前端框架,其官方文档 http://reactjs.cn/react/docs/getting-started.html 在介绍组件间通信时只给出了父子组件间通信的方法,而 ...

  8. React 精要面试题讲解(二) 组件间通信详解

    单向数据流与组件间通信 上文我们已经讲述过,react 单向数据流的原理和简单模拟实现.结合上文中的代码,我们来进行这节面试题的讲解: react中的组件间通信. 那么,首先我们把看上文中的原生js代 ...

  9. [转] React 中组件间通信的几种方式

    在使用 React 的过程中,不可避免的需要组件间进行消息传递(通信),组件间通信大体有下面几种情况: 父组件向子组件通信 子组件向父组件通信 跨级组件之间通信 非嵌套组件间通信 下面依次说下这几种通 ...

随机推荐

  1. 如何下载最新Xshell版本、免费官方正版软件的技巧过程

    我们在操作和管理Linux VPS.服务器的时候,肯定需要使用SSH工具,对于这个工具网上有很多免费和付费版本.对于我们用户来说肯定会较多的选择免费软件.其中使用较多的还是Xshell工具,也是我认为 ...

  2. 第一个HTML文档

    属性 和 值 1.作用 用来修饰元素 ex:让 p 标记的文本水平居中对齐 <p>Hello World</p> 2.语法      1.属性的声明必须位于开始标记里      ...

  3. JavaScript 实时 全角转半角

    //JavaScript全角字符转半角(参数str为input框输入的内容)var $fullChar2halfChar = function(str) { var result = ''; for ...

  4. μCOS-Ⅲ——常用注意事项

    **1,**main函数在调用其他函数之前必须先调用OSInit()函数对内核进行初始化. 2,所有的错误类型码都以OS_ERR_为前缀, 3,命名时尽量统一个格式,所有的函数.变量.宏定义和#def ...

  5. IP通信基础课堂笔记----第四章(重点中的重点)

    IPv4编址方法 一个IPv4地址可表示为一个32位的二进制数. IP地址前面的网络部分表示一个网段,后面部分(主机位)表示这个网段上的一台设备. 常用IP地址分为四类:A.B.C.D. 每类的网络地 ...

  6. OpenGL的一些名词

    搬运自:https://learnopengl-cn.github.io/01%20Getting%20started/10%20Review/ 词汇表 OpenGL: 一个定义了函数布局和输出的图形 ...

  7. IPhone微信H5用Video标签播放不了视频

    H5用Video标签播放视频 视频在安卓上可以正常播放,在苹果上却不能播放. 因为用了文件服务站点,而且不支持断点下载 把文件服务改成支持断点下载即可 断点下载参考(C#)

  8. 监控网络带宽 使用speedtest-cli命令

    1.监控网络带宽 使用speedtest-cli命令 l 安装命令: yum install python-pip –y pip install speedtest-cli l 运行命令: speed ...

  9. Zedboard搭建Linux嵌入式环境

    ZYNQ是ARM硬核和PL软核的结合体,Xillybus官方为他开发了驱动套件Xillinux,赶快将开发板投入使用吧! 本随笔参考了众多博主和官方教程:(基本上就是把官方教程翻译了一遍,呵呵:)) ...

  10. [ 随手记6 ] C/C++ 形参、实参、按值传参、指针传参、引用传参

    个人原创: 1. 形参:形式上的参数,一般多在函数声明.函数定义的参数上: 2. 实参:实体参数,有实际的值,在运算上被循环使用的值: 3. 按值传参:按值,就是把实际的值传给函数内部: 4. 指针传 ...