React Native DeviceEventEmitter/
2020-03-11 本文已影响0人
罗坤_23333
DeviceEventEmitter for android
JavaScript端
import { DeviceEventEmitter } from 'react-native';
// addListener
let context = null;
DeviceEventEmitter.addListener('YOUR_EVENTNAME', (msg) => {
console.log(msg);
console.log(this); // null
},context);
// emit
DeviceEventEmitter.emit('YOUR_EVENTNAME',msg);
//removeAllListeners
DeviceEventEmitter.removeAllListeners('YOUR_EVENTNAME');
Android拓展实现
import com.facebook.react.modules.core.DeviceEventManagerModule;
getReactApplicationContext().getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
.emit("YOUR_EVENTNAME", "msg");
最初DeviceEventEmitter是用于发送原生的BackPress点击事件,
所以Android通过DeviceEventEmitter.emit()
和Android RCTDeviceEventEmitter emit
都可以触发执行。
NativeEventEmitter for iOS
JavaScript端
import { NativeModules,NativeEventEmitter } from 'react-native';
const { IOSNativeModule } = NativeModules;
this._eventEmitter = new NativeEventEmitter(IOSNativeModule);
this._eventEmitter.addListener("IOS_EVENTNAME",(msg) => {
console.log(msg)
})
this._eventEmitter.removeAllListeners("IOS_EVENTNAME")
iOS拓展实现
.h
文件需要修改为继承RCTEventEmitter
#import <React/RCTBridgeModule.h>
+ #import <React/RCTEventEmitter.h>
- @interface AwesomeModule : NSObject <RCTBridgeModule>
+ @interface AwesomeModule : RCTEventEmitter <RCTBridgeModule>
@end
.m
文件
// 注册事件名称
- (NSArray<NSString *> *)supportedEvents
{
return @[@"EventReminder"];
}
// 派送指定名称的事件
[self sendEventWithName:@"EventReminder" body:@{@"name": data}];
Issue
-
Android可能存在的问题:
当不同NativeModule内emit()
相同的eventName时,android会存在监听事件都会被执行的问题。
所以在做原生拓展时,定义的eventName最好有独特的标识字符以防止其他NativeModule借用RCTDeviceEventEmitter
类时定义的eventName和您的重名。 -
iOS可能存在的问题:
首先,iOS不存在上述重名问题。
其次,必须使用new NativeEventEmitter()
来注册监听事件eventName。但是一旦注册成功,那么DeviceEventEmitter
也能监听到该eventName事件。如以下代码所示:
好处是下次监听时不需要再实例化一次this._eventEmitter = new NativeEventEmitter(IOSNativeModule); this._eventEmitter.addListener("IOS_EVENTNAME",(msg) => { console.log(msg) }) DeviceEventEmitter.addListener("IOS_EVENTNAME",(reminder) => { console.log(reminder.name); //“IOS_EVENTNAME”一旦被注册成功,这里也会被执行 })
NativeEventEmitter
,坏处是容易混淆监听事件。
所以建议仅针对iOS原生发送给JS的事件命名时添加IOS_
标识。
Reference
- [1] 原生拓展 getJSModule()
- [2] 更多补完文档请参阅 https://github.com/React-Sextant/react-native-bridge-docs