有时我们从native发送事件到javascript时希望能够根据javascript的处理结果回调native的相关处理逻辑,RN并没有直接提供相关机制,因此我们往往需要按照以下的方式来进行模拟:
Native发送event到JavaScript
[bridge enqueueJSCall:@"RCTDeviceEventEmitter" method:@"emit" args:@[@"demo", @"Request from Native"] completion:nil];
reactContext.getJSModule( DeviceEventManagerModule.RCTDeviceEventEmitter.class ).emit("demo", "Request from Native");
JavaScript监听event并做处理
import React from 'react'import { NativeModules, DeviceEventEmitter } from 'react-native';const { MyAppManager } = NativeModules;class MyApp extends React.PureComponent { componentWillMount() { DeviceEventEmitter.addListener('demo', (params) => { //doSomething.... MyAppManager.invokeCallback({ response: 'Response from JavaScript', }); }); } componentWillUnmount() { DeviceEventEmitter.removeListener('demo'); } }
注册MyAppManager
//MyAppManager.h#import <React/RCTBridgeModule.h>@interface MyAppManager : NSObject <RCTBridgeModule>@end//MyAppManager.m#import "MyAppManager.h"@implementation MyAppManagerRCT_EXPORT_MODULE(); RCT_EXPORT_METHOD(invokeCallback:(NSDictionary *)data) { //doSomething...}@end
package me.tom.myapp;import com.facebook.react.bridge.ReactApplicationContext;import com.facebook.react.bridge.ReactContextBaseJavaModule;import com.facebook.react.bridge.ReactMethod;import com.facebook.react.bridge.ReadableMap;public class MyAppManager extends ReactContextBaseJavaModule { public MyAppManager(ReactApplicationContext reactContext) { super(reactContext); } @Override public String getName() { return "MyAppManager"; } @ReactMethod public void invokeCallback(ReadableMap data) { //doSomething... } }
上述实例中,我们在监听事件的处理方法
中通过调用在native
中定义的MyAppManager#invokeCallback
方法来通知native
端进行后续处理的方式实现了我们一开始的需求。但这样的实现个人认为存在以下几个方面的问题:
JavaScript端必须手动调用
MyAppManager.invokeCallback(...)
,啰嗦且容易忘记。Native发送事件的地方一般是在UIViewController、Activity或Fragment中,因此
MyAppManager
还需要根据不用的参数将执行任务派发到相应真实的处理方法中,这里将充斥着大量的模版代码且易于出错。
针对上面的问题,个人简单的封装了一个库,上面的实例就可以简化为:
Native发送event到JavaScript并执行回调
#import "ZMReactEventEmitter.h"RCTBridge *bridge = .... ZMReactEventEmitter *eventEmitter = [ZMReactEventEmitter new]; [eventEmitter sendEvent:bridge name:@"demo" params:@"Request from Native" callback:^(id data) { //doSomething...}];
import me.tom.react.event.ReactEventEmitter;import me.tom.react.event.ReactEventEmitterCallbackHandler; ReactContext context = ...; ReactEventEmitter eventEmitter = new ReactEventEmitter(); eventEmitter.sendEvent(context, "demo", "Request from Native", new ReactEventEmitterCallbackHandler() { @Override public void handler(ReadableMap data) { //doSomething... } });
JavaScript监听事件并触发回调
import React from 'react';import ReactEventEmitter from 'rn-event-emitter-callback';class MyApp extends React.PureComponent { componentWillMount() { ReactEventEmitter.addListener('demo', (params, callback) => { //doSomething... callback('Response from React Native'); }) } componentWillUnmount() { ReactEventEmitter.removeListener('demo'); } }
作者:泪已无痕
链接:https://www.jianshu.com/p/e2f1b4c095e6
点击查看更多内容
为 TA 点赞
评论
共同学习,写下你的评论
评论加载中...
作者其他优质文章
正在加载中
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦