@@ -324,49 +324,32 @@ RCT_EXPORT_METHOD(updateStatusBarAnimation:(UIStatusBarAnimation)animation
324
324
325
325
## 给Javascript发送事件
326
326
327
- 即使没有被JavaScript调用,本地模块也可以给JavaScript发送事件通知。目前推荐的方式是继承`RCTEventEmitter`类,实现`suppportEvents`方法然后调用`self sendEventWithName`,如下:
327
+ 即使没有被JavaScript调用,本地模块也可以给JavaScript发送事件通知。最直接的方式是使用`eventDispatcher`:
328
328
329
329
```objective-c
330
- // CalendarManager.h
331
- #import <React/RCTBridgeModule.h>
332
- #import <React/RCTEventEmitter.h>
333
-
334
- @interface CalendarManager : RCTEventEmitter <RCTBridgeModule>
335
-
336
- @end
337
- ```
338
-
339
- ``` objective-c
340
- // CalendarManager.m
341
- #import " CalendarManager.h"
330
+ #import <React/RCTBridge.h>
331
+ #import <React/RCTEventDispatcher.h>
342
332
343
333
@implementation CalendarManager
344
334
345
- RCT_EXPORT_MODULE();
346
-
347
- - (NSArray<NSString * > * )supportedEvents
348
- {
349
- return @[ @"EventReminder"] ;
350
- }
335
+ @synthesize bridge = _bridge;
351
336
352
337
- (void)calendarEventReminderReceived:(NSNotification *)notification
353
338
{
354
339
NSString *eventName = notification.userInfo[@"name"];
355
- [ self sendEventWithName:@"EventReminder" body:@{@"name": eventName}] ;
340
+ [self.bridge.eventDispatcher sendAppEventWithName:@"EventReminder"
341
+ body:@{@"name": eventName}];
356
342
}
357
343
358
344
@end
359
345
```
360
346
361
- JS端可以在模块中创建一个新的NativeEventEmitter实例来订阅事件:
362
-
363
- ```
364
- import { NativeEventEmitter, NativeModules } from 'react-native';
365
- const { CalendarManager } = NativeModules;
347
+ 在JavaScript中可以这样订阅事件:
366
348
367
- const calendarManagerEmitter = new NativeEventEmitter(CalendarManager);
349
+ ``` javascript
350
+ import { NativeAppEventEmitter } from ' react-native' ;
368
351
369
- const subscription = calendarManagerEmitter .addListener(
352
+ var subscription = NativeAppEventEmitter .addListener (
370
353
' EventReminder' ,
371
354
(reminder ) => console .log (reminder .name )
372
355
);
@@ -377,6 +360,37 @@ subscription.remove();
377
360
378
361
更多的给JavaScript发送事件的例子,参见[ ` RCTLocationObserver ` ] ( https://github.com/facebook/react-native/blob/master/Libraries/Geolocation/RCTLocationObserver.m ) .
379
362
363
+ ## 优化无监听处理的事件
364
+
365
+ 如果你发送了一个事件却没有任何监听处理,则会因此收到一个资源警告。要优化因此带来的额外开销,你可以在你的` RCTEventEmitter ` 子类中覆盖` startObserving ` 和` stopObserving ` 方法。
366
+
367
+ ``` objective-c
368
+ @implementation CalendarManager
369
+ {
370
+ bool hasListeners;
371
+ }
372
+
373
+ // 在添加第一个监听函数时触发
374
+ -(void)startObserving {
375
+ hasListeners = YES;
376
+ // Set up any upstream listeners or background tasks as necessary
377
+ }
378
+
379
+ // Will be called when this module's last listener is removed, or on dealloc.
380
+ -(void)stopObserving {
381
+ hasListeners = NO;
382
+ // Remove upstream listeners, stop unnecessary background tasks
383
+ }
384
+
385
+ - (void)calendarEventReminderReceived:(NSNotification * )notification
386
+ {
387
+ NSString * eventName = notification.userInfo[ @"name"] ;
388
+ if (hasListeners) { // Only send events if anyone is listening
389
+ [ self sendEventWithName:@"EventReminder" body:@{@"name": eventName}] ;
390
+ }
391
+ }
392
+ ```
393
+
380
394
## 从Swift导出
381
395
382
396
Swift不支持宏,所以从Swift向React Native导出类和函数需要多做一些设置,但是大致与Objective-C是相同的。
0 commit comments