组件间通信方式

1.父子组件之间数据传递

1.1父子组件之间数据传递-props方式

  • 父组件通过props向子组件传递数据
  • 子组件通过调用父组件放在props中的方法,触发父组件获取子组件数据的方法来实现父组件获取子组件的数据
import React, {
    
     Component } from 'react'

class Child extends Component {
    
    
  getParentValue = () => {
    
    //获取父组件中传递过来的数据
    let {
    
     obj } = this.props;
    console.log(obj);
  }
  sendValueToParent = () => {
    
    //触发发送值到父组件的方法
    let {
    
     getChildrenValue } = this.props;//获取父组件中传递过来获取子组件数据的方法
    getChildrenValue({
    
    //调用该方法并传入子组件的值
      sex: '男',
      id: 1
    })
  }
  render() {
    
    
    return (
      <div>
        <h2>这里是子组件</h2>
        <button onClick={
    
    this.getParentValue}>获取父组件传过来的值</button>
        <button onClick={
    
    this.sendValueToParent}>向父组件传递子组件的值</button>
      </div>
    )
  }
}

export default class Parent extends Component {
    
    
  state = {
    
    //定义父组件的数据
    obj: {
    
     name: '张三', age: 16 }
  }
  getChildrenValue = (childObj) => {
    
    //当子组件触发了获取子组件数据的方法的时候,就获取到了子组件传过来的数据
    let {
    
     obj } = this.state;
    obj = {
    
     ...obj, ...childObj };//更新数据
    this.setState({
    
    //设置数据
      obj
    })
  }
  render() {
    
    
    return (
      <div>
        <h2>这里是父组件</h2>
        <Child obj={
    
    this.state.obj} getChildrenValue={
    
    this.getChildrenValue}></Child>
      </div>
    )
  }
}

1.2父子组件之间消息传递-render方式

  • 这个功能类似于vueslot插槽功能,它能在父组件中给子组件预留出一个位置,来放置子组件
import React, {
    
     Component } from 'react';

class Child extends Component {
    
    
  render() {
    
    
    return (
      <div className='child'>
        <h2>这里是子组件</h2>
        {
    
    /* 这块就是预留给 <Child render={(params)=>{return(<这里面写的就是预留位置的组件 params={params}></这里面写的就是预留位置的组件>)}}></Child> */}
        {
    
    
          this.props.render({
    
     name: 'child', id: 2 })
        }
        <footer>这是子组件的尾部</footer>
      </div>
    )
  }
}

class Son extends Component {
    
    
  render() {
    
    
    console.log(this);
    return (
      <div className='son'>
        <h2>这里是孙组件</h2>
      </div>
    )
  }
}

export default class Parent extends Component {
    
    
  render() {
    
    
    return (
      <div className='parent'>
        <h2>这里是父组件</h2>
        <Child render={
    
    (obj) => {
    
    
          return (<Son obj={
    
    obj}></Son>)
        }}>
        </Child>
      </div>
    )
  }
}

2.任意组件之间消息传递

2.1消息订阅发布模式

  • 适用于任意组件之间的消息传递
  • 使用方式
    • 在需要发送数据的组件中发布消息
    • 在需要接受数据的组件的生命周期componentDidMount 中订阅消息,并在componentWillUnmount中取消订阅
import React, {
    
     Component } from 'react';
import Pubsub from 'pubsub-js';

class Child1 extends Component {
    
    
  sendValueToOtherCom = () => {
    
    
    Pubsub.publish('sendValueToChild2', {
    
    //发布消息
      name: 'child1',
      value: '你好!'
    })
  }
  render() {
    
    
    return (
      <div>
        <h2>这里是子组件1</h2>
        <button onClick={
    
    this.sendValueToOtherCom}>向子组件2发送数据</button>
      </div>
    )
  }
}
class Child2 extends Component {
    
    
  render() {
    
    
    return (
      <div>
        <h2>这里是子组件2</h2>
      </div>
    )
  }
  componentDidMount() {
    
    //在componentDidMount中订阅消息
    this.token = Pubsub.subscribe('sendValueToChild2', (msg, data) => {
    
    //订阅消息
      //msg:发布消息的事件名称
      //data:发布消息的数据
      console.log(msg, data);
    })
  }
  componentWillUnmount() {
    
    //在组件将要卸载的时候取消订阅消息
    PubSub.unsubscribe(this.token);
  }
}

export default class Parent extends Component {
    
    
  render() {
    
    
    return (
      <div>
        <h2>这里是父组件</h2>
        <Child1></Child1>
        <Child2></Child2>
      </div>
    )
  }
}

2.2redux模式

链接: redux

3.祖先组件和后代组件间通信-conText方式

  • 一种组件间通信方式,常用于【祖先组件】和【后代组件】间通信
  • 注意:在应用开发中一般不用context,一般都用它封装react插件
  • 概念
    //1. 创建Context容器对象
    const MyContext = React.createContext();
    
    //2.渲染子组件时候,外面包裹xxxContext.Provider,通过value属性给后代传递数据
    <MyContext.Provider value={
          
          {
          
           name: '张三', age: 16 }}>
    	<Parent></Parent>
    </MyContext.Provider>
    
    //3.后代组件读数据
    //3.1仅仅适用于类组件
    	static contextType = MyContext//声明接受context
    	this.contetxt//读取context中value的数据
    //3.2函数式组件和类式组件都可以
     <MyContext.Consumer>
            {
          
          
              value => {
          
          //value就是context中value的数据
                console.log(value);
                return (
                  <p>{
          
          value.name}-{
          
          value.age}</p>
                )
              }
            }
    </MyContext.Consumer>
    

3.1适用于类组件

import React, {
    
     Component } from 'react';

const MyContext = React.createContext();//1.创建Context容器对象
class Child extends Component {
    
    
  render() {
    
    
    return (
      <div>
        <h2>这里是子组件</h2>
        <Son></Son>
      </div>
    )
  }
}
class Son extends Component {
    
    
  static contextType = MyContext//3.声明接受context contextType不能变
  render() {
    
    
    console.log(this.context);
    return (
      <div>
        <h2>这里是孙子组件</h2>
      </div>
    )
  }
}

export default class Parent extends Component {
    
    
  render() {
    
    
    return (
      <div>
        <h2>这里是父组件</h2>
        {
    
    /* 2.渲染子组件时候,外面包裹xxxContext.Provider,通过value属性给后代传递数据 */}
        <MyContext.Provider value={
    
    {
    
     name: '张三', age: 16 }}>
          <Child></Child>
        </MyContext.Provider>
      </div>
    )
  }
}

3.2适用于函数组件和类组件

import React, {
    
     Component } from 'react';

const MyContext = React.createContext();//1.创建Context容器对象
class Child extends Component {
    
    
  render() {
    
    
    return (
      <div>
        <h2>这里是子组件</h2>
        <Son></Son>
      </div>
    )
  }
}

function Son() {
    
    
  return (
    <div>
      <h2>这里是孙子组件</h2>
      <MyContext.Consumer>
        {
    
    
          value => {
    
    //3.value就是context中value的数据
            console.log(value);//{ name: '张三', age: 16 }
          }
        }
      </MyContext.Consumer>
    </div>
  )
}

export default class Parent extends Component {
    
    
  render() {
    
    
    return (
      <div>
        <h2>这里是父组件</h2>
        {
    
    /* 2.渲染子组件时候,外面包裹xxxContext.Provider,通过value属性给后代传递数据 */}
        <MyContext.Provider value={
    
    {
    
     name: '张三', age: 16 }}>
          <Child></Child>
        </MyContext.Provider>
      </div>
    )
  }
}

猜你喜欢

转载自blog.csdn.net/big_sun_962464/article/details/113408391