热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

ReactNative中事件监听DeviceEventEmitter

基本语法react-native中事件监听时使用插件DeviceEventEmitter这个来进行实现,在这里我们进行讲解一下基本语法,如下所示1.

基本语法

react-native中事件监听时使用插件DeviceEventEmitter这个来进行实现,在这里我们进行讲解一下基本语法,如下所示

1.设置监听

在想要接受监听的地方进行添加监听,假如是one.js页面

import { DeviceEventEmitter } from 'react-native';
...
componentDidMount() {//收到监听this.listener = DeviceEventEmitter.addListener('通知名称', (message) => {//收到监听后想做的事情console.log(message); //监听})
}
componentWillUnmount() {//移除监听if (this.listener) {this.listener.remove();}}
...

从上面代码中,我们能够看到通过DeviceEventEmitter进行设置了监听,根据React-Native生命周期,当组件加载的时候,我们进行监听,当组件卸载的时候,我们移除监听事件

2.触发监听

在我们需要触发one.js页面的监听的时候,我们能够在其他页面进行处罚,假定触发页面为two.js,则代码如下所示:

import { DeviceEventEmitter } from 'react-native';
...
startEmit() {//准备值,发监听const message = '监听';DeviceEventEmitter.emit('通知名称', message);
}
...

实例操作

在这里我们使用两个页面进行验证全局监听事件,在这里我们使用"react-navigation"(“1.5.12”),跳转界面,首先我们去实现第一个界面,在这个界面用于设置监听,代码如下所示:

import React, { Component } from 'react';
import { Button, Text, View, DeviceEventEmitter } from &#39;react-native&#39;;class One extends Component {constructor(props) {super(props);this.state &#61; { result: &#39;我是默认值&#39; };}componentDidMount() {// 收到监听this.listener &#61; DeviceEventEmitter.addListener(&#39;changeResult&#39;, (message) &#61;> {// 收到监听后想做的事情 // 监听this.setState({ result: message });});}componentWillUnmount() {// 移除监听if (this.listener) { this.listener.remove(); }}_onChange &#61; () &#61;> {const { navigation } &#61; this.props;navigation.navigate(&#39;Two&#39;);};render() {return (<View style&#61;{{ flex: 1, justifyContent: &#39;center&#39;, alignItems: &#39;center&#39; }}><Button onPress&#61;{this._onChange} title&#61;"跳转到第二个页面" /><Text style&#61;{{ fontSize: 20, marginTop: 30 }}>{this.state.result}</Text></View>);}
}
export default One;

之后我们完成第二个界面&#xff0c;在这个界面&#xff0c;我们进行对第一个界面监听事件的触发&#xff0c;代码如下所示&#xff1a;

import React, { Component } from &#39;react&#39;;
import { Button, View, DeviceEventEmitter } from &#39;react-native&#39;;
class Two extends Component {startEmit &#61; () &#61;> {// 准备值&#xff0c;发监听const message &#61; &#39;监听发出通过&#xff0c;让one页面的值进行改变&#39;;DeviceEventEmitter.emit(&#39;changeResult&#39;, message);};render() {return (<View style&#61;{{ flex: 1, justifyContent: &#39;center&#39;, alignItems: &#39;center&#39; }}><Button onPress&#61;{this.startEmit} title&#61;"触发第一个页面的监听事件" /></View>);}
}
export default Two;

现在我们来看看具体的显示效果&#xff1a;

[emit]

源码说明

既然基本用法我们能够使用了&#xff0c;那么我们就找找看能不能看到源码信息&#xff0c;我们通过在one.js页面中点击(command&#43;左键) DeviceEventEmitter插件&#xff0c;我们能够看到如下界面代码&#xff1a;

DeviceEventEmitter

在 // Plugins处我们能够看到这一行代码 get DeviceEventEmitter() { return require(&#39;RCTDeviceEventEmitter&#39;); }, 也就是说我们 DeviceEventEmitter 在底层实现是RCTDeviceEventEmitter&#xff0c;那么我们就可以更加深入的查看下去&#xff0c;我们能够在Libaray文件夹中看到如下界面&#xff1a;

[emit]
之后找到 RCTDeviceEventEmitter.js 文件&#xff0c;如下代码&#xff0c;就是我从中复制的代码

/*** Deprecated - subclass NativeEventEmitter to create granular event modules instead of* adding all event listeners directly to RCTDeviceEventEmitter.*/
class RCTDeviceEventEmitter extends EventEmitter {sharedSubscriber: EventSubscriptionVendor;constructor() {const sharedSubscriber &#61; new EventSubscriptionVendor();super(sharedSubscriber);this.sharedSubscriber &#61; sharedSubscriber;}addListener(eventType: string, listener: Function, context: ?Object): EmitterSubscription {if (__DEV__) {checkNativeEventModule(eventType);}return super.addListener(eventType, listener, context);}removeAllListeners(eventType: ?string) {if (__DEV__) {checkNativeEventModule(eventType);}super.removeAllListeners(eventType);}removeSubscription(subscription: EmitterSubscription) {if (subscription.emitter !&#61;&#61; this) {subscription.emitter.removeSubscription(subscription);} else {super.removeSubscription(subscription);}}
}module.exports &#61; new RCTDeviceEventEmitter();

从代码中&#xff0c;我们能够看出实现了的方法有addListener,但是没有我们在使用中的其他方法&#xff0c;我们对代码进行分析&#xff0c;可以看到&#xff0c;在这里进行引入了下面这两个文件

const EventEmitter &#61; require(&#39;EventEmitter&#39;);
const EventSubscriptionVendor &#61; require(&#39;EventSubscriptionVendor&#39;);

于是我们能够看到如下界面&#xff1a;


能够看到我们需要的文件&#xff0c;打开EventEmitter.js文件&#xff0c;能够看到其实现代码了&#xff0c;内容如下所示&#xff1a;

/*** Copyright (c) 2015-present, Facebook, Inc.** This source code is licensed under the MIT license found in the* LICENSE file in the root directory of this source tree.** &#64;providesModule EventEmitter* &#64;noflow* &#64;typecheck*/
&#39;use strict&#39;;const EmitterSubscription &#61; require(&#39;EmitterSubscription&#39;);
const EventSubscriptionVendor &#61; require(&#39;EventSubscriptionVendor&#39;);const emptyFunction &#61; require(&#39;fbjs/lib/emptyFunction&#39;);
const invariant &#61; require(&#39;fbjs/lib/invariant&#39;);/*** &#64;class EventEmitter* &#64;description* An EventEmitter is responsible for managing a set of listeners and publishing* events to them when it is told that such events happened. In addition to the* data for the given event it also sends a event control object which allows* the listeners/handlers to prevent the default behavior of the given event.** The emitter is designed to be generic enough to support all the different* contexts in which one might want to emit events. It is a simple multicast* mechanism on top of which extra functionality can be composed. For example, a* more advanced emitter may use an EventHolder and EventFactory.*/
class EventEmitter {_subscriber: EventSubscriptionVendor;_currentSubscription: ?EmitterSubscription;/*** &#64;constructor** &#64;param {EventSubscriptionVendor} subscriber - Optional subscriber instance* to use. If omitted, a new subscriber will be created for the emitter.*/constructor(subscriber: ?EventSubscriptionVendor) {this._subscriber &#61; subscriber || new EventSubscriptionVendor();}/*** Adds a listener to be invoked when events of the specified type are* emitted. An optional calling context may be provided. The data arguments* emitted will be passed to the listener function.** TODO: Annotate the listener arg&#39;s type. This is tricky because listeners* can be invoked with varargs.** &#64;param {string} eventType - Name of the event to listen to* &#64;param {function} listener - Function to invoke when the specified event is* emitted* &#64;param {*} context - Optional context object to use when invoking the* listener*/addListener(eventType: string, listener: Function, context: ?Object): EmitterSubscription {return (this._subscriber.addSubscription(eventType,new EmitterSubscription(this, this._subscriber, listener, context)) : any);}/*** Similar to addListener, except that the listener is removed after it is* invoked once.** &#64;param {string} eventType - Name of the event to listen to* &#64;param {function} listener - Function to invoke only once when the* specified event is emitted* &#64;param {*} context - Optional context object to use when invoking the* listener*/once(eventType: string, listener: Function, context: ?Object): EmitterSubscription {return this.addListener(eventType, (...args) &#61;> {this.removeCurrentListener();listener.apply(context, args);});}/*** Removes all of the registered listeners, including those registered as* listener maps.** &#64;param {?string} eventType - Optional name of the event whose registered* listeners to remove*/removeAllListeners(eventType: ?string) {this._subscriber.removeAllSubscriptions(eventType);}/*** Provides an API that can be called during an eventing cycle to remove the* last listener that was invoked. This allows a developer to provide an event* object that can remove the listener (or listener map) during the* invocation.** If it is called when not inside of an emitting cycle it will throw.** &#64;throws {Error} When called not during an eventing cycle** &#64;example* var subscription &#61; emitter.addListenerMap({* someEvent: function(data, event) {* console.log(data);* emitter.removeCurrentListener();* }* });** emitter.emit(&#39;someEvent&#39;, &#39;abc&#39;); // logs &#39;abc&#39;* emitter.emit(&#39;someEvent&#39;, &#39;def&#39;); // does not log anything*/removeCurrentListener() {invariant(!!this._currentSubscription,&#39;Not in an emitting cycle; there is no current subscription&#39;);this.removeSubscription(this._currentSubscription);}/*** Removes a specific subscription. Called by the &#96;remove()&#96; method of the* subscription itself to ensure any necessary cleanup is performed.*/removeSubscription(subscription: EmitterSubscription) {invariant(subscription.emitter &#61;&#61;&#61; this,&#39;Subscription does not belong to this emitter.&#39;);this._subscriber.removeSubscription(subscription);}/*** Returns an array of listeners that are currently registered for the given* event.** &#64;param {string} eventType - Name of the event to query* &#64;returns {array}*/listeners(eventType: string): [EmitterSubscription] {const subscriptions: ?[EmitterSubscription] &#61; (this._subscriber.getSubscriptionsForType(eventType): any);return subscriptions? subscriptions.filter(emptyFunction.thatReturnsTrue).map(function(subscription) {return subscription.listener;}): [];}/*** Emits an event of the given type with the given data. All handlers of that* particular type will be notified.** &#64;param {string} eventType - Name of the event to emit* &#64;param {...*} Arbitrary arguments to be passed to each registered listener** &#64;example* emitter.addListener(&#39;someEvent&#39;, function(message) {* console.log(message);* });** emitter.emit(&#39;someEvent&#39;, &#39;abc&#39;); // logs &#39;abc&#39;*/emit(eventType: string) {const subscriptions: ?[EmitterSubscription] &#61; (this._subscriber.getSubscriptionsForType(eventType): any);if (subscriptions) {for (let i &#61; 0, l &#61; subscriptions.length; i < l; i&#43;&#43;) {const subscription &#61; subscriptions[i];// The subscription may have been removed during this event loop.if (subscription) {this._currentSubscription &#61; subscription;subscription.listener.apply(subscription.context,Array.prototype.slice.call(arguments, 1));}}this._currentSubscription &#61; null;}}/*** Removes the given listener for event of specific type.** &#64;param {string} eventType - Name of the event to emit* &#64;param {function} listener - Function to invoke when the specified event is* emitted** &#64;example* emitter.removeListener(&#39;someEvent&#39;, function(message) {* console.log(message);* }); // removes the listener if already registered**/removeListener(eventType: String, listener) {const subscriptions: ?[EmitterSubscription] &#61; (this._subscriber.getSubscriptionsForType(eventType): any);if (subscriptions) {for (let i &#61; 0, l &#61; subscriptions.length; i < l; i&#43;&#43;) {const subscription &#61; subscriptions[i];// The subscription may have been removed during this event loop.// its listener matches the listener in method parametersif (subscription && subscription.listener &#61;&#61;&#61; listener) {subscription.remove();}}}}
}module.exports &#61; EventEmitter;

上述代码中&#xff0c;我们能够找到我们在one.js和two.js中使用的方法&#xff0c;如addListener通过传递字符串类型的事件类型&#xff0c;监听使用的方法和上下文进行添加订阅&#xff0c;如下所示&#xff1a;

addListener(eventType: string, listener: Function, context: ?Object): EmitterSubscription {return (this._subscriber.addSubscription(eventType,new EmitterSubscription(this, this._subscriber, listener, context)) : any);}

还有emit方法&#xff0c;通过事件类型&#xff0c;遍历所有的订阅事件进行获取指定eventType的subscriptions详细信息&#xff0c;然后通过apply方法将参数传递给上下文&#xff0c;如下所示代码&#xff1a;

emit(eventType: string) {const subscriptions: ?[EmitterSubscription] &#61; (this._subscriber.getSubscriptionsForType(eventType): any);if (subscriptions) {for (let i &#61; 0, l &#61; subscriptions.length; i < l; i&#43;&#43;) {const subscription &#61; subscriptions[i];// The subscription may have been removed during this event loop.if (subscription) {this._currentSubscription &#61; subscription;subscription.listener.apply(subscription.context,Array.prototype.slice.call(arguments, 1));}}this._currentSubscription &#61; null;}}

也就是我们发起请求时message信息的处理方式&#xff0c;在这过程中&#xff0c;当然还有其他几处代码进行了事件处理&#xff0c;在这里就不一一说明了


以上就是DeviceEventEmitter的使用


推荐阅读
  • 本文讨论了一个关于cuowu类的问题,作者在使用cuowu类时遇到了错误提示和使用AdjustmentListener的问题。文章提供了16个解决方案,并给出了两个可能导致错误的原因。 ... [详细]
  • Java太阳系小游戏分析和源码详解
    本文介绍了一个基于Java的太阳系小游戏的分析和源码详解。通过对面向对象的知识的学习和实践,作者实现了太阳系各行星绕太阳转的效果。文章详细介绍了游戏的设计思路和源码结构,包括工具类、常量、图片加载、面板等。通过这个小游戏的制作,读者可以巩固和应用所学的知识,如类的继承、方法的重载与重写、多态和封装等。 ... [详细]
  • Linux重启网络命令实例及关机和重启示例教程
    本文介绍了Linux系统中重启网络命令的实例,以及使用不同方式关机和重启系统的示例教程。包括使用图形界面和控制台访问系统的方法,以及使用shutdown命令进行系统关机和重启的句法和用法。 ... [详细]
  • Iamtryingtomakeaclassthatwillreadatextfileofnamesintoanarray,thenreturnthatarra ... [详细]
  • Spring源码解密之默认标签的解析方式分析
    本文分析了Spring源码解密中默认标签的解析方式。通过对命名空间的判断,区分默认命名空间和自定义命名空间,并采用不同的解析方式。其中,bean标签的解析最为复杂和重要。 ... [详细]
  • 本文介绍了设计师伊振华受邀参与沈阳市智慧城市运行管理中心项目的整体设计,并以数字赋能和创新驱动高质量发展的理念,建设了集成、智慧、高效的一体化城市综合管理平台,促进了城市的数字化转型。该中心被称为当代城市的智能心脏,为沈阳市的智慧城市建设做出了重要贡献。 ... [详细]
  • 向QTextEdit拖放文件的方法及实现步骤
    本文介绍了在使用QTextEdit时如何实现拖放文件的功能,包括相关的方法和实现步骤。通过重写dragEnterEvent和dropEvent函数,并结合QMimeData和QUrl等类,可以轻松实现向QTextEdit拖放文件的功能。详细的代码实现和说明可以参考本文提供的示例代码。 ... [详细]
  • 开发笔记:加密&json&StringIO模块&BytesIO模块
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了加密&json&StringIO模块&BytesIO模块相关的知识,希望对你有一定的参考价值。一、加密加密 ... [详细]
  • android listview OnItemClickListener失效原因
    最近在做listview时发现OnItemClickListener失效的问题,经过查找发现是因为button的原因。不仅listitem中存在button会影响OnItemClickListener事件的失效,还会导致单击后listview每个item的背景改变,使得item中的所有有关焦点的事件都失效。本文给出了一个范例来说明这种情况,并提供了解决方法。 ... [详细]
  • Java容器中的compareto方法排序原理解析
    本文从源码解析Java容器中的compareto方法的排序原理,讲解了在使用数组存储数据时的限制以及存储效率的问题。同时提到了Redis的五大数据结构和list、set等知识点,回忆了作者大学时代的Java学习经历。文章以作者做的思维导图作为目录,展示了整个讲解过程。 ... [详细]
  • 本文介绍了OC学习笔记中的@property和@synthesize,包括属性的定义和合成的使用方法。通过示例代码详细讲解了@property和@synthesize的作用和用法。 ... [详细]
  • 1,关于死锁的理解死锁,我们可以简单的理解为是两个线程同时使用同一资源,两个线程又得不到相应的资源而造成永无相互等待的情况。 2,模拟死锁背景介绍:我们创建一个朋友 ... [详细]
  • Spring特性实现接口多类的动态调用详解
    本文详细介绍了如何使用Spring特性实现接口多类的动态调用。通过对Spring IoC容器的基础类BeanFactory和ApplicationContext的介绍,以及getBeansOfType方法的应用,解决了在实际工作中遇到的接口及多个实现类的问题。同时,文章还提到了SPI使用的不便之处,并介绍了借助ApplicationContext实现需求的方法。阅读本文,你将了解到Spring特性的实现原理和实际应用方式。 ... [详细]
  • eclipse学习(第三章:ssh中的Hibernate)——11.Hibernate的缓存(2级缓存,get和load)
    本文介绍了eclipse学习中的第三章内容,主要讲解了ssh中的Hibernate的缓存,包括2级缓存和get方法、load方法的区别。文章还涉及了项目实践和相关知识点的讲解。 ... [详细]
  • sklearn数据集库中的常用数据集类型介绍
    本文介绍了sklearn数据集库中常用的数据集类型,包括玩具数据集和样本生成器。其中详细介绍了波士顿房价数据集,包含了波士顿506处房屋的13种不同特征以及房屋价格,适用于回归任务。 ... [详细]
author-avatar
心如止水向北飞2012_737
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有