React组件之间的通信

242 阅读1分钟

简单概要为以下几种通信模式:

  1. 父组件 -> 子组件
  2. 子组件 -> 父组件
  3. 跨级组件
  4. 非嵌套关系的组件, 兄弟组件

第一种情况: 父组件 -> 子组件

// 子组件: Child
const Child = props => {
  // 子组件通过props来接收父组件传入的属性
  return <p>{props.name}</p>
}

// 父组件: Parent
const Parent = ()=>{
    // 给子组件传入属性name
    return <Child name="rexhang"></Child>
}

第二种情况: 子组件 -> 父组件

// 子组件: Child
const Child = props =>{
  function log(msg){
      console.log(msg);
  }
  // 通过与父组件约定的属性来回传内容
  props.bridge && props.bridge({log});
  return <div>I Am Child Component.</div>
}

// 父组件: Parent
class Parent extends Component {
    getChild = ({log, ...args}) => {
        // 注册/定义一个属性, 通过此属性来调用子组件传来的内容
        // 获取到子组件传来的内容并可调用
        log('rexhang');
    }
    render(){
        return <Child bridge={this.getChild}></Child>        }
}

第三种情况: 跨级组件

// context方式实现跨级组件通信 
// context设计目的是为了共享那些对于一个组件树而言是"全局"的数据

// context.js
import React, { createContext } from 'react';
export default createContext();

// 孙组件: GrandChild
import Context from 'context.js';
const GrandChild = function Grandson(props) {
  return <Context.Consumer>
    {
      context => {
        console.log(context);
        return <div>i am Grandson Components. {JSON.stringify(context)}</div>
      }
    }
  </Context.Consumer>
}

// 子组件: Child
const Child = () =>{
    return (
        <GrandChild />
    )
}
// 父组件: Parent
import Context from 'context.js';
class Parent extends Component {
      state = {
          name: "rexhang",
          age: 18
      }
      render(){
          return (
            <Context.Provider value={{...this.state}}>              <Child />
            </Context.Provider>           )
      }
}

第四种情况: 非嵌套关系的组件, 兄弟组件

  • redux 全局状态管理

  • 兄弟组件可以通过找到兄弟节点共同的父节点,结合父子组件通信模式进行处理

  • 自定义事件通信-发布订阅模式 eg: pubsub-js...