《React+Redux前端开发实战》—2.3.4 非嵌套组件通信
2.3.4 非嵌套组件通信
非嵌套组件就是没有包含关系的组件。这类组件的通信可以考虑通过事件的发布-订阅模式或者采用context来实现。
如果采用context,就是利用组件的共同父组件的context对象进行通信。利用父级实现中转传递在这里不是一个好的方案,会增加子组件和父组件之间的耦合度,如果组件层次嵌套较深的话,不易找到父组件。
那么发布-订阅模式是什么呢?发布-订阅模式又叫观察者模式。其实很简单,举个现实生活中的例子:
很多人手机上都有微信公众号,读者所关注的公众号会不定期推送信息。
这就是一个典型的发布-订阅模式。在这里,公众号就是发布者,而关注了公众号的微信用户就是订阅者。关注公众号后,一旦有新文章或广告发布,就会推送给订阅者。这是一种一对多的关系,多个观察者(关注公众号的微信用户)同时关注、监听一个主体对象(某个公众号),当主体对象发生变化时,所有依赖于它的对象都将被通知。
发布-订阅模式有以下优点:
耦合度低:发布者与订阅者互不干扰,它们能够相互独立地运行。这样就不用担心开发过程中这两部分的直接关系。
易扩展:发布-订阅模式可以让系统在无论什么时候都可进行扩展。
易测试:能轻易地找出发布者或订阅者是否会得到错误的信息。
灵活性:只要共同遵守一份协议,不需要担心不同的组件是如何组合在一起的。
React在非嵌套组件中只需要某一个组件负责发布,其他组件负责监听,就能进行数据通信了。下面通过代码来演示这种实现。
非嵌套组件通信示例:
(1)安装一个现成的events包:
npm install events —save
(2)新建一个公共文件events.js,引入events包,并向外提供一个事件对象,供通信时各个组件使用:
import { EventEmitter } from "events";
export default new EventEmitter();
(3)组件App.js:
import React, { Component } from 'react';
import ComponentA from "./ComponentA";
import ComponentB from "./ComponentA";
import "./App.css";
export default class App extends Component{
render(){
return(
<div>
<ComponentA />
<ComponentB />
</div>
);
}
}
(4)组件ComponentA:
import React,{ Component } from "react";
import emitter from "./events";
export default class ComponentA extends Component{
constructor(props) {
super(props);
this.state = {
data: React,
};
}
componentDidMount(){
// 组件加载完成以后声明一个自定义事件
// 绑定callMe事件,处理函数为addListener()的第2个参数
this.eventEmitter = emitter.addListener("callMe",(data)=>{
this.setState({
data
})
});
}
componentWillUnmount(){
// 组件销毁前移除事件监听
emitter.removeListener(this.eventEmitter);
}
render(){
return(
<div>
Hello,{ this.state.data }
</div>
);
}
}
(5)组件ComponentB:
import React,{ Component } from "react";
import emitter from "./events";
export default class ComponentB extends Component{
render(){
const cb = (data) => {
return () => {
// 触发自定义事件
// 可传多个参数
emitter.emit("callMe", "World")
}
}
return(
<div>
<button onClick = { cb("Hey") }>点击</button>
</div>
);
}
}
当在非嵌套组件B内单击按钮后,会触发emitter.emit(),并且将字符串参数World传给callMe。组件A展示的内容由Hello,React变为Hello,World。这就是一个典型的非嵌套组件的通信。
注意:组件之间的通信要保持简单、干净,如果遇到了非嵌套组件通信,这时候读者需要仔细审查代码设计是否合理。要尽量避免使用跨组件通信和非嵌套组件通信等这类情况。
- 点赞
- 收藏
- 关注作者
评论(0)