Skip to content

(5)非嵌套组件间通信 ​

本节目标:理解“(5)非嵌套组件间通信”的核心思路,并能把它用于实际开发或面试表达。 非嵌套组件,就是没有任何包含关系的组件,包括兄弟组件以及不在同一个父级中的非兄弟组件。对于非嵌套组件,可以采用下面两种方式:

  • 利用二者共同父组件的 context 对象进行通信
  • 使用自定义事件的方式
  • 全局变量

第一种:如果采用组件间共同的父级来进行中转,会增加子组件和父组件之间的耦合度,如果组件层次较深的话,找到二者公共的父组件不是一件容易的事,当然还是那句话,也不是不可以...

第二种:这里我们采用自定义事件的方式来实现非嵌套组件间的通信。 我们需要使用一个 events 包: npm install events --save 新建一个 ev.js,引入 events 包,并向外提供一个事件对象,供通信时使用:

import { EventEmitter } from "events";
export default new EventEmitter();
// App.js

:

import React, { Component } from 'react';
import Foo from "./Foo";
import Boo from "./Boo";
import "./App.css";
export default class App extends Component {
  render() {
    return (
      <div>
        <Foo />
        <Boo />
      </div>
    );
  }
}
// Foo.js

:

import React, { Component } from "react";
import emitter from "./ev"
export default class Foo extends Component {
  constructor(props) {
    super(props);
    this.state = {
      msg: null,
    };
  }
  componentDidMount() {
    //

声明一个自定义事件

    //

在组件装载完成以后

    this.eventEmitter = emitter.addListener("callMe", (msg) => {
      this.setState({
        msg
      })
    });
  }
  //

组件销毁前移除事件监听

  componentWillUnmount() {
    emitter.removeListener(this.eventEmitter);
  }
  render() {
    return (
      <div>
        { this.state.msg}
        {/*

我是非嵌套 1 号

 */}
      </div>
    );
  }
}
// Boo.js

:

import React, { Component } from "react";
import emitter from "./ev"
export default class Boo extends Component {
  render() {
    const cb = (msg) => {
      return () => {
        //

触发自定义事件

        emitter.emit("callMe", "Hello")
      }
    }
    return (
      <div>

我是非嵌套 2 号

        <button onClick={cb("blue")}>

点击我

</button>
      </div>
    );
  }
}

自定义事件是典型的发布/订阅模式,通过向事件对象上添加监听器和触发事件来实现组件间通信。

本站总访问 — 次