从其超级视图中删除后,JS根视图是否将始终接收来自本机的事件?

时间:2018-07-10 23:14:04

标签: react-native react-native-ios

我的(经过简化的)代码如下:

// objc
self.currentSwipeUpView = [[RCTRootView alloc]
   initWithBridge:_bridge moduleName:@"PhotoSwipeUpView"
   initialProperties:nil
];
// elsewhere...
[self.currentSwipeUpView removeFromSuperview];
self.currentSwipeUpView = nil;

// js
function PhotoSwipedUpView() {
    return <TextInput style={{flex: 1}} onChangeText={console.warn} />
}
AppRegistry.registerComponent('PhotoSwipeUpView', () => PhotoSwipeUpView)

self.currentSwipeUpView从其父视图中删除并取消引用。发生这种情况时,JS线程是否可能不会收到未决的onChangeText事件?会导致console.warn与新文本一起出现吗?

我正在想象这样一种情况:在RCTRootView从其超级视图中删除并取消引用后,该事件将被发送到JS线程。

此外,我很好奇是否有可能在从JS端从其超级视图中删除RCTRootView时得到通知。

我正在使用ARC,并且没有持有对self.currentSwipeUpView的任何其他引用。

编辑:我有两个RCTRootViews。它们中只有一个将被卸载,另一个将在整个应用程序状态中保持不变。他们使用相同的网桥,因此使用相同的bundle和JS环境。

1 个答案:

答案 0 :(得分:0)

加载/卸载JS软件包

您加载的js捆绑包绑定到了根视图,并且除了在那个视图中之外都不是持久的。 从根视图的父视图中删除该捆绑包后,该捆绑包也会被卸载。如果根视图已被删除并取消引用,则文本更改侦听器也应被删除且不应触发。

捆绑中的JSX用于最终设置本机元素及其侦听器。 JSX基本上是脚本。具有RN TextInput的JSX基本上会生成本机UITextField。如果JSX指定了侦听器,则用于文本更改的本机侦听器将添加到本机元素实例。

即使加载了两个根视图,它们也将彼此独立地运行。如果卸载了一个根视图,则与屏幕上的TextInputs关联的侦听器将不再接收事件。您的第二个根视图应该不受影响,因为它将为TextInput设置单独的侦听器。

事件/计时问题

我认为定时的机会很小,并且取决于调用removeFromSuperview的位置,js可能会在视图完全删除并取消引用之前接收事件,但是如果这样做可能会影响功能对于您的应用程序,我建议您使用其他模式与您的数据进行交互并删除屏幕。

可能的解决方案

很难不知道您要做什么,但是您可以例如使用RCTEventEmitter / NativeEventEmitter发布通知以关闭React Native视图,然后让React本机屏幕使用本机功能关闭自身,该功能只是将其从超级视图中删除。这种类型的模式也会(在某种意义上)回答您的第二个问题,因为您可以有效地告诉RN屏幕,然后再关闭它,以便在删除之前采取任何必要的措施。

相关问题