我创建了UI。它运作良好。但我不知道如何将数据从Java发送到JS?在本机模块中,我可以使用回调并激活这个onClick事件。但在UI我不知道。
更多关于我需要的东西。
我有android组件。以这种方式发送给JS createViewInstance(ThemedReactContext reactContext)
用户在组件内部发生了变化。我在java类中看到了这些变化。当JS要求时,我需要将这些更改发送给JS。
您知道如何将数据从UI组件发送到JS吗?请举个例子。 谢谢。
答案 0 :(得分:16)
在gre's answer that put me on the right track, but still left me with a lot of work to do的基础上,我将尝试解释一些遗漏的细节。
有两种基本方法可以做到这一点:
正如gre所提到的,React Native文档在Native UI Components section of Events中解释了这一点。
他们展示了如何使用以下代码发送事件:
WritableMap event = Arguments.createMap();
event.putString("message", "MyMessage");
ReactContext reactContext = (ReactContext)getContext();
reactContext.getJSModule(RCTEventEmitter.class).receiveEvent(
getId(), "topChange", event);
有了这个解释:
事件名称
topChange
映射到onChange
回调道具 JavaScript(映射在UIManagerModuleConstants.java
)。
UIManagerModuleConstants.java
的实际定义如下:
"topChange",
MapBuilder.of(
"phasedRegistrationNames",
MapBuilder.of(
"bubbled", "onChange",
"captured", "onChangeCapture")))
即。通过在Android代码中使用事件topChange
,由于此映射,您可以使用onChange
或onChangeCapture
在JS中拦截它。
你可以在那里找到许多其他现有的事件来捎带。
也有宣称的“直接”事件可能更有用:
"topLayout",
MapBuilder.of("registrationName", "onLayout")
即。 Android事件topLayout
映射到JS事件回调onLayout
(I do not understand the difference between the "bubbled" vs "captured" vs "direct" event types)
要在JS中接收活动,请注意文档中引用的3个地点_onChange()
:
创建回调方法:_onChange(event: Event) {}
在构造函数中绑定它:this._onChange = this._onChange.bind(this);
在创建自定义视图时传递它:return <RCTMyCustomView {...this.props} onChange={this._onChange} />;
自定义事件需要在使用之前声明到系统,将Android事件映射到JS事件的方式与上面的React Native完成它们的方式类似。
这是通过覆盖ViewManager
中的以下方法之一来完成的:
getExportedCustomBubblingEventTypeConstants()
getExportedCustomDirectEventTypeConstants()
javadoc非常有助于展示映射应该如何工作,但我发现在上面提到的UIManagerModuleConstants
中引用React Native代码很有用。
在那里宣布它之后,就像使用任何其他“现有”事件一样使用它。
我想将点击事件从Android发送到JS,并将其称为onClick
。我选择使用“直接”事件。我还选择在Android和JS中使用相同的名称 - 这不是必需的。
需要修改3个文件:
ViewManager类
此代码将Android事件名称“onClick”映射到JS函数“onClick”。
/**
* This method maps the sending of the "onClick" event to the JS "onClick" function.
*/
@Nullable @Override
public Map<String, Object> getExportedCustomDirectEventTypeConstants() {
return MapBuilder.<String, Object>builder()
.put("onClick",
MapBuilder.of("registrationName", "onClick"))
.build();
}
查看课程
此视图在单击视图时向JS发送事件。这里使用的名称是Android事件名称,它将映射到您在ViewManager
类中设置的任何内容。
// trigger the onPress JS callback
super.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
final Context context = getContext();
if (context instanceof ReactContext) {
((ReactContext) context).getJSModule(RCTEventEmitter.class)
.receiveEvent(getId(),
"onClick", null);
}
}
});
instanceof
检查是因为这个视图有时会从React上下文之外的本机代码中引用。
React Native JS组件
在构造函数中绑定:
constructor(props) {
super(props);
this.onClick = this.onClick.bind(this);
}
声明实际的回调函数:
onClick(event: Event) {
// do something
}
确保set the callback when rendering your view:
render() {
return <NativeView onClick={this.onClick} />;
}
如果这样布局,一切都非常简单,但更精细细节的文档散布在网络上。
答案 1 :(得分:14)
http://facebook.github.io/react-native/docs/native-components-android.html#events
^这显示了如何在UI组件上触发从Java端到JS的事件。
但是对于&#34;自定义事件&#34; (非预定义的事件喜欢onLoad,onScroll等。)您还需要覆盖getExportedCustomDirectEventTypeConstants
。
这是一个示例,为gl-react-native触发onGLProgress:
(3)在JS方面,您可以提供onGLProgress
道具回调。