React Native 应用程序在解除模式或操作后神秘地冻结 sheet
React Native app mysteriously freezes after dismissing a modal or action sheet
我遇到了一个问题,每次我在 React Native 应用程序中关闭模式、操作 sheet 或警报时,应用程序都会完全冻结并且无法与之交互。
导航到新堆栈或单击按钮不会重现。
我必须关闭应用程序并重新启动才能再次交互。通过打包程序重新加载应用程序没有帮助。
我们的代码可以在一个模式被关闭时自动显示一个新的模式,而且它确实有效——模式是可交互的。所以看起来只有底层内容被冻结了,就好像顶部还有一个模态但是它是不可见的。
疯狂的是,这是在以前已知的良好分支中进行复制。所以本地 config/cache 一定有什么变化,但我不知道是什么。我重新克隆了 repo,清除了 watchman/packager/yarn 缓存,擦除了所有数据的模拟器。没有解决问题。
打包程序 xcode 或 Flipper 中也没有日志表明可能出了什么问题。
使用 react-native-modal
、@expo/react-native-action-sheet
和内置的 React Native Alert(虽然不使用通用的 Expo 框架)。我已经将这些库升级到最新版本。
运行没主意了。我还能在哪里看到这里?
更新:超精简代码重现。此模态自动显示、自动关闭,然后按钮不可按下。从代码中删除模式使按钮可按下。
function TestApp() {
const [isVisible, setVisible] = useState(true);
return (
<>
<TouchableOpacity style={{ padding: 80 }} delayPressIn={0}>
<Text>Touch</Text>
</TouchableOpacity>
<Modal isVisible={isVisible} onShow={() => setVisible(false)}>
<Text>Foo</Text>
</Modal>
</>
);
}
如果我添加一个最小警报调用而不是模式,也会发生同样的情况。在这种情况下,我会在 5 秒后显示另一个可交互的警报。 只有弹出窗口是可交互的 - 例如警报和模式。
useEffect(() => Alert.alert("alert"), []);
useEffect(() => {
setTimeout(() => Alert.alert("5s alert"), 5000);
}, []);
更新 #2
看起来每个新的“弹出窗口”样式 UI 都会使之前的 UI 无法交互。
如果我像上面那样关闭第一个 Alert
,那么我将无法与底层 TouchableOpacity
交互,但我 可以 与第二个交互(5 秒)Alert
.
但是,如果我不关闭第一个警报,而第二个警报弹出,我只能关闭第二个警报,而不能与保持冻结状态的第一个警报交互。
一般情况下,模态框通常伴随着覆盖 layer/background 掩码。当你关闭模态时,你是否也确定你正在关闭覆盖层,因为如果有任何透明层,它可以阻止对其他控件的触摸。
对我来说,只有当 Flipper 布局插件对我的应用程序处于活动状态时才会发生冻结。 Disabled the layout plugin,重新启动 Flipper,重新启动我的应用程序,冻结问题消失了。
这是由于运送的 Flipper 版本过时所致。将 ios/Podfile
中的 use_flipper!
替换为 use_flipper!('Flipper' => '0.54.0')
,运行 pod install
应该可以解决问题。
我遇到了一个问题,每次我在 React Native 应用程序中关闭模式、操作 sheet 或警报时,应用程序都会完全冻结并且无法与之交互。
导航到新堆栈或单击按钮不会重现。
我必须关闭应用程序并重新启动才能再次交互。通过打包程序重新加载应用程序没有帮助。
我们的代码可以在一个模式被关闭时自动显示一个新的模式,而且它确实有效——模式是可交互的。所以看起来只有底层内容被冻结了,就好像顶部还有一个模态但是它是不可见的。
疯狂的是,这是在以前已知的良好分支中进行复制。所以本地 config/cache 一定有什么变化,但我不知道是什么。我重新克隆了 repo,清除了 watchman/packager/yarn 缓存,擦除了所有数据的模拟器。没有解决问题。
打包程序 xcode 或 Flipper 中也没有日志表明可能出了什么问题。
使用 react-native-modal
、@expo/react-native-action-sheet
和内置的 React Native Alert(虽然不使用通用的 Expo 框架)。我已经将这些库升级到最新版本。
运行没主意了。我还能在哪里看到这里?
更新:超精简代码重现。此模态自动显示、自动关闭,然后按钮不可按下。从代码中删除模式使按钮可按下。
function TestApp() {
const [isVisible, setVisible] = useState(true);
return (
<>
<TouchableOpacity style={{ padding: 80 }} delayPressIn={0}>
<Text>Touch</Text>
</TouchableOpacity>
<Modal isVisible={isVisible} onShow={() => setVisible(false)}>
<Text>Foo</Text>
</Modal>
</>
);
}
如果我添加一个最小警报调用而不是模式,也会发生同样的情况。在这种情况下,我会在 5 秒后显示另一个可交互的警报。 只有弹出窗口是可交互的 - 例如警报和模式。
useEffect(() => Alert.alert("alert"), []);
useEffect(() => {
setTimeout(() => Alert.alert("5s alert"), 5000);
}, []);
更新 #2
看起来每个新的“弹出窗口”样式 UI 都会使之前的 UI 无法交互。
如果我像上面那样关闭第一个 Alert
,那么我将无法与底层 TouchableOpacity
交互,但我 可以 与第二个交互(5 秒)Alert
.
但是,如果我不关闭第一个警报,而第二个警报弹出,我只能关闭第二个警报,而不能与保持冻结状态的第一个警报交互。
一般情况下,模态框通常伴随着覆盖 layer/background 掩码。当你关闭模态时,你是否也确定你正在关闭覆盖层,因为如果有任何透明层,它可以阻止对其他控件的触摸。
对我来说,只有当 Flipper 布局插件对我的应用程序处于活动状态时才会发生冻结。 Disabled the layout plugin,重新启动 Flipper,重新启动我的应用程序,冻结问题消失了。
这是由于运送的 Flipper 版本过时所致。将 ios/Podfile
中的 use_flipper!
替换为 use_flipper!('Flipper' => '0.54.0')
,运行 pod install
应该可以解决问题。