Appearance
(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>
);
}
}自定义事件是典型的发布/订阅模式,通过向事件对象上添加监听器和触发事件来实现组件间通信。
