我正在按照此处的指南在 React Native 中创建 Turbo 模块。 https://reactnative.dev/docs/next/the-new-architecture/pillars-turbomodules
如何在 iOS 上发出事件?该文档仅显示如何从 React 调用本机函数,而不显示如何从 Turbo 模块发出事件。
对于 Android,您会获得一个
ReactApplicationContext
对象,它允许您使用上下文对象创建这样的发射器。
private val emitter = context.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
emitter.emit(eventName, eventArray)
如何在 iOS 上做同样的事情?
要从 iOS 向 RN 发送事件,您应该创建自己的发射器类,该类继承自
RCTEventEmitter
,然后使用 NativeEventEmitter
在 JS 端初始化它,并使用 addListener
: 添加所需事件的侦听器
EventEmitter.h
#import <React/RCTEventEmitter.h>
@interface EventEmitter : RCTEventEmitter
+ (instancetype)shared;
@end
EventEmitter.m
#import "EventEmitter.h"
// Events
static NSString* onMyEvent = @"onMyEvent";
// Variable to save the instance
static EventEmitter* eventEmitter = nil;
@implementation EventEmitter
/// Exposing "EventEmitter" name to RN
RCT_EXPORT_MODULE(EventEmitter);
// Called from RN
- (instancetype)init {
if (self = [super init]) {
eventEmitter = self;
}
return self;
}
+ (BOOL)requiresMainQueueSetup {
return NO;
}
+ (instancetype)shared {
return eventEmitter;
}
// List of supported events
- (NSArray<NSString *> *)supportedEvents {
return @[onMyEvent];
}
@end
如何致电:
NSDictionary* body = @{@"message" : @"Hello Emitter!"};
[EventEmitter.shared sendEventWithName:@"onMyEvent" body:body];
RN/JS
import {
...
NativeEventEmitter,
NativeModules,
} from 'react-native';
import type EmitterSubscription from 'react-native';
class EventHandler extends React.Component {
eventsSubscription: EmitterSubscription;
componentDidMount() {
const eventEmitter = new NativeEventEmitter(NativeModules.EventEmitter);
this.eventsSubscription = eventEmitter.addListener('onMyEvent', event => {
console.log(event.message); // Prints "Hello Emitter!"
});
}
componentWillUnmount() {
this.eventsSubscription.remove();
}
...
};
就我而言,接受的答案不足以使其发挥作用。
分支上的本教程(React Native 社区组织的一部分)
feat/swift-event-emitter
帮助我让它发挥作用:
https://github.com/react-native-community/RNNewArchitectureLibraries/tree/feat/swift-event-emitter
特别是我的 JSI 规范中缺少的这些行:
addListener: (eventType: string) => void;
removeListeners: (count: number) => void;