欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

react没有嵌套关系的组件之间通信方法详解

程序员文章站 2024-03-15 10:57:17
...

一、在react中,没有嵌套关系的组件之间的通信方式主要有2种:


a、拥有共同父组件的兄弟组件之间可以使用context。

具体使用方法可以参考:https://www.jianshu.com/p/a8717edadb18


b、非兄弟组件之间利用事件的发布订阅模式。


1)事件的发布订阅模式是什么?首先需要一个发布者,和一个或多个订阅者。假如我家有一个水果店,张三来我家买苹果,正好我家苹果卖完了,我就告诉他一个电话号码,让他回去等电话,苹果一到货,我就通知他(但是他可以选择再去买或者不去买,只是我一定会通知他),同样李四也是同样的需求,我给出了同样的解决方案,以此类推。。。等苹果到货了,我会按照先后顺序挨个给所有的预订者打电话通知。在这个事件当中,张三和李四就是订阅者,而我就是发布者,我打电话通知他们的动作就是发布者对订阅事件的处理函数。所以在react组件之间的通信场景里,只要组件1负责订阅(监听事件),组件2负责发布(触发事件)就可以进行数据交流。


2)如何实现?核心代码如下:


//组件1(负责订阅事件和取消订阅事件)

import emitter from './events';

componentDidMount () { //在组件挂载完成后声明一个自定义事件
	emitter.addListener('callMe', (msg) => {
		this.setState({
			msg: msg
		})
	})
}}

componentWillUnmount () { //组件销毁前移除事件监听
	emitter.removeListener('callMe', (msg) => {
		this.setState({
			msg: msg
		})
)

//组件2(负责发布事件)

import emitter from './events';

render () {
	function publ(){
		return function () {
			emitter.emit('callMe', '我是发布者');
		}
	}

	return (
		<div>
			我是负责发布事件的组件2 <button onClick = {publ()}>点击我</button>
		</div>
	)
}

可以看的出来,我们在组件内分别引入一个events包,它提供了监听、发布、删除等事件处理方法,是一个在浏览器端实现了node事件机制的包。源码解析可以参考:http://blog.csdn.net/leoleocs/article/details/50162065


这里我们主要用到3个核心方法:事件监听(订阅)、事件触发(发布)和事件删除(取消订阅)。现在来理解一下这3个方法的底层实现原理(需要自行参照源码来理解):


事件监听:addListener方法,首先需要传入2个参数(type, lintener),事件名称和对应的处理函数。然后定义一个_events空对象,用来存储订阅事件列表,当组件挂载完成以后,程序会自动触发这个方法进行遍历所有监听事件,并以数组的形式存储起来。


事件触发:emit方法,它只需要传入type参数,即要发布的事件名称。当用户触发此方法的时候,首先需要通过事件名称找对应的事件处理函数handler,调用isFunction方法检测它是否为一个函数,如果是,通过call和apply方法将函数执行者指向当前调用的对象,并将事件处理函数作为参数传入。


事件删除:removeListener方法,它也需要传入2个参数(type, lintener),事件名称和对应的处理函数。当组件即将销毁之前自动触发此方法,先得到当前事件的处理函数,然后与传入的处理函数lintener对比,如果二者一样,则直接删除,如果lintener还处于等待触发的队列中,则直接退出队列。