react中的父子组件通信和跨级组件通信

父子组件通信

顾名思义就是父组件和子组件之间进行通信交流。下面先看样例代码:

// 父子组件通信
import React from "react";

// 下面为父子组件通信实例代码
// 父组件
class ParentSon extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      msg: "father",
      name: "partent",
      age: 60
    };
  }

  callback = (msg, name, age) => {
    this.setState({ msg });
    this.setState({ name });
    this.setState({ age });
  };

  render() {
    return (
      <div style={{padding: 30+'px'}}>
        <h1>{this.state.msg}</h1>
        <Child
          callback={this.callback}
          age={this.state.age}
          name={this.state.name}
        ></Child>
      </div>
    );
  }
}

// 子组件
class Child extends React.Component{
  constructor(props){
    super(props);
    this.state={
      msg: 'I am son',
      name: 'son',
      age: 8
    };
    // 下面一行代码是为了解决非箭头函数使用时this的指向问题不能指向当前子组件自身
    // this.change=this.change.bind(this);
  }
  // change(){
  //   // console.log(this);
  //   this.props.callback(this.state.msg,this.state.name,this.state.age);
  // }
  change=()=>{
    this.props.callback(this.state.msg,this.state.name,this.state.age);
  }

  render(){
    return (
      <div>
        <div>{this.props.name}</div>
        <div>{this.props.age}</div>
        <button onClick={this.change}>点击</button>
      </div>
    )
  }
}

export default ParentSon;

如上面代码所示,分别创建了父组件 ParentSon 和子组件 Child ,父组件里面定义了自己的state内容,并定义了一个 callback 方法,此方法用来改变父组件自身的state内容值的,然后render函数里面除了渲染自身state里的msg值之外,将自身的callback方法以及自身state里的name,age分别作为参数传给了子组件 Child。

下面再继续看子组件内部,除了有自己的state之外,还有一个change方法,然后render函数里渲染了来自props里的值以及一个点击事件按钮,而这个按钮点击事件就会触发调用自身那个change事件,在进入change方法内部会看到,实际上,执行的就是props接收的callback方法,也就是从父组件传过来的那个callback,而这里的参数又是子组件自身state的内容值,到此,我们可以顺一下整个思路了。

思路: 一开始渲染出的全是父组件的值(因为子组件显示的就是来自父组件的值)-----> 点击按钮 -----> 触发子组件change事件(实际接收的父组件callback方法)-----> 父组件callback被调用,父组件的state里的值都发生改变,此时已变成和子组件state里一样的值了 -----> state改变后的值,又通过props传给了子组件Child -----> 再一次渲染出来传过来的值,即和子组件一模一样的值,此时整个过程全部结束。

跨级组件通信

顾名思义就是互不相干且之间隔了好几级的一种通信交流方式。下面先看样例代码:

// 跨级组件通信
import React from "react";

const ThemeContext = React.createContext("light");

class ContextMess extends React.Component {
  static contextType = ThemeContext;
  render() {
    return (
      <ThemeContext.Provider value="dark">
        <div style={{padding: 30+'px'}}>
          <h3>{this.context}</h3>
          <Toolbar></Toolbar>
        </div>
      </ThemeContext.Provider>
    );
  }
}

class Toolbar extends React.Component {
  render() {
    return (
      <div>
        <ThemedButton></ThemedButton>
      </div>
    );
  }
}

class ThemedButton extends React.Component {
  static contextType = ThemeContext;
  render() {
    return (
      <div>
        <h1>{this.context}</h1>
        <ThemeContext.Consumer>
          {value => (<h6>{value}</h6>)}
        </ThemeContext.Consumer>
      </div>
    );
  }
}

export default ContextMess;

从上面代码可以看出,有三个组件,ContextMess ,Toolbar ,ThemedButton ,ContextMess 为最外层组件,依次是Toolbar 组件,再是ThemedButton 组件,逐层嵌套。
代码中主要使用了react中的Context技术点,使用了Context中的以下几个API:React.createContext,Context.Provider,Class.contextType,Context.Consumer。

React.createContext: 创建一个 Context 对象。当 React 渲染一个订阅了这个 Context 对象的组件,这个组件会从组件树中离自身最近的那个匹配的 Provider 中读取到当前的 context 值。

Context.Provider: 每个 Context 对象都会返回一个 Provider React 组件,它允许消费组件订阅 context 的变化;Provider 接收一个 value 属性,传递给消费组件;当 Provider 的 value 值发生变化时,它内部的所有消费组件都会重新渲染。

Class.contextType: (代码中通过 static 来定义静态属性contextType,即组件(class)自己的属性,等同于class.contextType)挂载在 class 上的 contextType 属性会被重赋值为一个由 React.createContext() 创建的 Context 对象。这能让你使用 this.context 来消费最近 Context 上的那个值。你可以在任何生命周期中访问到它,包括 render 函数中。

Context.Consumer: 这里,React 组件也可以订阅到 context 变更。这能让你在函数式组件中完成订阅 context;这需要函数作为子元素(function as a child)这种做法。这个函数接收当前的 context 值,返回一个 React 节点。传递给函数的 value 值等同于往上组件树离这个 context 最近的 Provider 提供的 value 值。如果没有对应的 Provider,value 参数等同于传递给 createContext() 的 defaultValue。

思路: 简单来说,那个‘light’一开始创建的就相当于要在其他组件使用的数据,在 ContextMess 组件中通过使用 contextType 获取 createContext 创建的对象,然后通过this.context来获取值,即“light”;除此之外,使用 Context.Provider API 通过value参数将当前值改为“dark”,然后不使用 props 传值方式,在二级组件中可以看到,并没有使用props接收值,最后在下一级组件通过 Class.contextType 和 this.context 方式读取值,除此之外还使用 Context.Consumer API 来获取最近的那个匹配的context值,即改变后的值“dark”。

具体Context相关知识及API使用请点击:React中Context的学习使用
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值