React Native原生模块与JS模块通信的几种方式
React Native原生模块与JS模块通信的几种方式在做React Native开发的时候避免不了的需要原生模块和JS之间进行数据传递,这篇文章将向大家分享原生模块向JS传递数据的几种方式。 方式一:通过Callbacks的方式说起Callbacks大家都不陌生,它是最常用的设计模式之一。无论是Java,Object-c,C#,还是JavaScript等都会看到Callbacks的身影。 原生模块支持Callbacks类型的参数,该Callbacks对应JS中的function。 在原生模块中: public class RNTestModule extends ReactContextBaseJavaModule{
public RNTestModule(ReactApplicationContext reactContext) {
super(reactContext);
}
@Override
public String getName() {
return "RNTest";
}
@ReactMethod
public void measureLayout(
int tag,int ancestorTag,Callback errorCallback,Callback successCallback) {
try {
measureLayout(tag,ancestorTag,mMeasureBuffer);
map.putDouble("relativeX",1);
map.putDouble("relativeY",1);
map.putDouble("width",2);
map.putDouble("height",3);
successCallback.invoke(relativeX,relativeY,width,height);
} catch (IllegalViewOperationException e) {
errorCallback.invoke(e.getMessage());
}
}
在上述代码中, 在JS模块中: RNTest.measureLayout(
100,100,(msg) => {
console.log(msg);
},(x,y,height) => {
console.log(x + ':' + y + ':' + width + ':' + height);
}
);
上述代码,是在JS模块中调用原生模块的方法 通过上述的方式,JS调用原生模块的
方式二:通过Promises的方式Promises是ES6的一个新的特性,在React Native中你会看到Promises的大量使用。 在原生模块中: public class RNTestModule extends ReactContextBaseJavaModule{
public RNTestModule(ReactApplicationContext reactContext) {
super(reactContext);
}
@Override
public String getName() {
return "RNTest";
}
@ReactMethod
public void measureLayout(
int tag,Promise promise) {
try {
WritableMap map = Arguments.createMap();
map.putDouble("relativeX",1);
map.putDouble("relativeY",1);
map.putDouble("width",2);
map.putDouble("height",3);
promise.resolve(map);
} catch (IllegalViewOperationException e) {
promise.reject(e);
}
}
}
上述代码中,
在JS模块中: async test() {
try {
var {
relativeX,height,} = await RNTest.measureLayout(100,100);
console.log(relativeX + ':' + relativeY + ':' + width + ':' + height);
} catch (e) {
console.error(e);
}
}
在上述代码中,通过ES7的新特性async/await来修饰了 如果,不希望以同步的形式调用,可以这样写: test2(){
RNTest.measureLayout(100,100).then(e=>{
console.log(e.relativeX + ':' + e.relativeY + ':' + e.width + ':' + e.height);
this.setState({
relativeX:e.relativeX,relativeY:e.relativeY,width:e.width,height:e.height,})
}).catch(error=>{
console.log(error);
});
}
以上就是通过Promises的方式向JS传递数据的方式,小伙伴们看懂了吗。 上述两种方式,通过Callbacks的方式与通过Promises的方式,都可以向JS模块传递数据,但都是只能传递一次。 方式三:通过发送事件的方式原生模块支持另外一种向JS模块传递数据的方式,通过发送事件的方式。 原生模块,可以向JS传递事件而不要而不需要直接的调用,就像Android中的广播,iOS中的通知中心。 下面就向大家演示通过 在原生模块中: @Override
public void onHandleResult(String barcodeData) {
WritableMap params = Arguments.createMap();
params.putString("result",barcodeData);
sendEvent(getReactApplicationContext(),"onScanningResult",params);
}
private void sendEvent(ReactContext reactContext,String eventName,@Nullable WritableMap params) {
reactContext.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
.emit(eventName,params);
}
上述代码向JS模块发送了一个名为“onScanningResult”的事件,并携带了“params”作为参数。 在JS模块中: 下面是在JS代码中进行监听原生模块发出的名为“onScanningResult”的事件。 componentDidMount() {
//注册扫描监听
DeviceEventEmitter.addListener('onScanningResult',this.onScanningResult);
}
onScanningResult = (e)=> {
this.setState({
scanningResult: e.result,});
// DeviceEventEmitter.removeListener('onScanningResult',this.onScanningResult);//移除扫描监听
}
在JS中通过
另外,JS模块也支持通过 三种方式的优缺点
最后既然来了,留下个喜欢再走吧,鼓励我继续创作(^_^)∠※ 如果喜欢我的文章,那就关注我的博客吧,让我们一起做朋友~~ 戳这里,加关注哦:
(编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |