前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >react组件间的通信

react组件间的通信

作者头像
OECOM
发布2020-07-02 09:28:50
6410
发布2020-07-02 09:28:50
举报
文章被收录于专栏:OECOMOECOM

在使用react过程中,不可避免的需要组件间的数据通信,数据通信一般情况有一下几种情况:

  1. 父组件向子组件通信
  2. 子组件向父组件通信
  3. 跨级组件之间通信
  4. 非嵌套组件间通信

下面将依次来说一下这几种组件间通信的解决办法。

父组件向子组件通信

这种通信方式是最常见的一种,解决方法就是通过props来进行通信,子组件接收到props后再进行相应的处理。

代码语言:javascript
复制
import React,{Component} from 'react';
import Header from './header'
import './father.less';

class Father extends Component{
  constructor(){
    super();
    this.state={
      myName:"张三"
    }
  }
  render(){
    return (
      <div className="container">
        <Header title={this.state.myName}/>
      </div>
    )
  }
}
export default Father

上面代码为father组件,在其内部引入了header子组件,并将自己的state中的myName传递给header组件,定义名称为title,在子组件中可以通过this.props.title来获取到值。

代码语言:javascript
复制
import React,{Component} from 'react';
import './header.less';

class Header extends Component{
  render(){
    return (
      <div className="components-header row">
        {this.props.myName}
      </div>
    )
  }
}
export default Header

上述代码就是一个简单的父组件向子组件来传递数据。当然,为了保证程序的严谨性,在子组件中我们可以对传递过来的props进行类型校验,如果类型校验没有通过,则会抛出一个错误,已提醒调用组件者。

代码语言:javascript
复制
import React,{Component} from 'react';
import './header.less';

class Header extends Component{
  propsType:{
    title:React.propsTypes.String
  }
  render(){
    return (
      <div className="components-header row">
        {this.props.myName}
      </div>
    )
  }
}
export default Header

如此即完成了对于传递过来的参数校验。

子组件向父组件通信

子组件向父组件通信可以通过回调函数的方式来进行,我们还是将上面的代码来修改一下。

先看father组件

代码语言:javascript
复制
import React,{Component} from 'react';
import Header from './header'

class Father extends Component{
  constructor(){
    super();
    this.state={
      myName:"张三"
    }
  }
  showChildName(name){
    console.log(name);
  }
  render(){
    return (
      <div className="container">
        <Header showName={this.showChildName.bind(this)}/>
      </div>
    )
  }
}
export default Father

其次是子组件

代码语言:javascript
复制
import React,{Component} from 'react';
import './header.less';

class Header extends Component{
  propsType:{
    showName:React.propsTypes.Func
  }
  constructor(){
    super();
    this.state={
      myName:"header"
    }
  }
  showName(){
    let myName = this.state.myName;
    this.props.showName(myName)
  }
  render(){
    return (
      <div className="components-header row">
        <button onClick={this.showName.bind(this)}>按钮</button>
      </div>
    )
  }
}
export default Header

跨组件通信

所谓跨级组件通信,就是父组件向子组件的子组件通信,向更深层的子组件通信。跨级组件通信可以采用下面两种方式:中间组件层层传递props;使用context对象

对于第一种方式,如果父组件结构较深,那么中间的每一层组件都要去传递 props,增加了复杂度,并且这些 props 并不是这些中间组件自己所需要的。不过这种方式也是可行的,当组件层次在三层以内可以采用这种方式,当组件嵌套过深时,采用这种方式就需要斟酌了。 使用 context 是另一种可行的方式,context 相当于一个全局变量,是一个大容器,我们可以把要通信的内容放在这个容器中,这样一来,不管嵌套有多深,都可以随意取用。 使用 context 也很简单,需要满足两个条件:

  1. 上级组件要声明自己支持 context,并提供一个函数来返回相应的 context 对象
  2. 子组件要声明自己需要使用 context

下面请看一个例子

代码语言:javascript
复制
import React, { Component } from 'react';
import Sub from "./Sub";
import "./App.css";

export default class App extends Component{
    // 父组件声明自己支持 context
    static childContextTypes = {
        color:React.propTypes.string,
        callback:React.propTypes.func,
    }
    // 父组件提供一个函数,用来返回相应的 context 对象
    getChildContext(){
        return{
            color:"red",
            callback:this.callback.bind(this)
        }
    }
    callback(msg){
        console.log(msg)
    }
    render(){
        return(
            <div>
                <Sub></Sub>
            </div>
        );
    }
}

sub组件

代码语言:javascript
复制
import React from "react";
import SubSub from "./SubSub";

const Sub = (props) =>{
    return(
        <div>
            <SubSub />
        </div>
    );
}

export default Sub;

subsub组件(孙子组件)

代码语言:javascript
复制
import React,{ Component } from "react";
import PropTypes from "prop-types";

export default class SubSub extends Component{
    // 子组件声明自己需要使用 context
    static contextTypes = {
        color:PropTypes.string,
        callback:PropTypes.func,
    }
    render(){
        const style = { color:this.context.color }
        const cb = (msg) => {
            return () => {
                this.context.callback(msg);
            }
        }
        return(
            <div style = { style }>
                SUBSUB
                <button onClick = { cb("孙子组件信息") }>按钮</button>
            </div>
        );
    }
}

跨组件通信

跨组件通信的方式适用于以上所有的通信方式,这种方式是通过发布/订阅者模式来实现,需要安装PubSub

首先是通过npm来安装pubsub

代码语言:javascript
复制
npm install pubsub-js --save

页面中引入

代码语言:javascript
复制
import PubSub from 'pubsub-js'

pubsub有三中操作,分别是发布消息,订阅消息,取消订阅

代码语言:javascript
复制
发送消息:PubSub.publish(名称,参数)
订阅消息:PubSub.subscrib(名称,函数)
取消订阅:PubSub.unsubscrib(名称)

首先发送消息需要顶一个名称,以供给订阅消息的名称来确定订阅哪个消息,基本上是一个键值对的形式,参数是该键的值,当在组件中注册了订阅消息以后,相当与注册了一个监听事件,当有发布消息发出,订阅消息就会接收到,并在订阅消息的函数中进行自定义处理。取消订阅相当于是取消该监听事件。

home组件

代码语言:javascript
复制
import React, { Component } from 'react';  
import PubSub from 'pubsub-js';  
class Home extends Component {  
  constructor(props){  
    super(props);  
    this.state={  
      increase:'increase',  
      decrease:'decrease'  
    }  
  }  
  buttonIncrease(){  
    PubSub.publish('PubSubmessag',this.state.increase);  
  }  
  buttonDecrease(){  
     PubSub.publish('PubSubmessage', this.state.decrease);  
  }  
  render() {  
    return (  
      <div>  
        Some state changes:  
        <button onClick={this.buttonIncrease.bind(this)}>Increase</button>  
        <button onClick={this.buttonDecrease.bind(this)}>Decrease</button>  
      </div>  
    )  
  }  
}  
export default Home;

子组件

代码语言:javascript
复制
import React, { Component } from 'react';  
import { Link} from 'react-router-dom';  
import PubSub from 'pubsub-js';  
  
export default class App extends Component{  
constructor(props){  
  super(props);  
  this.state={  
    increase:'none',  
  }  
}  
componentDidMount(){  
  this.pubsub_token = PubSub.subscribe('PubSubmessage', function (topic,message) {  
    this.setState({  
      increase: message  
    });  
  }.bind(this));  
}  
componentWillUnmount(){  
  PubSub.unsubscribe(this.pubsub_token);  
}  
  render() {  
  return (  
    <div>  
      <header>  
        Links:       
        <Link to="/App/home">Home</Link>     
      </header>   
      <div style={{ marginTop: '1.5em' }}>{ this.props.children}</div>  
      <div style={{ marginTop: '1.5em' }}>{ this.state.increase}</div>  
    </div>  
  )  
}  
}
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2018-02-01,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 父组件向子组件通信
  • 子组件向父组件通信
  • 跨组件通信
  • 跨组件通信
相关产品与服务
容器服务
腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档