-
-
Notifications
You must be signed in to change notification settings - Fork 615
Description
Description
When dismissing a fullScreenModal screen via router.dismiss() (which sends a POP action triggering native dismissViewControllerAnimated:), the app freezes completely. The UI becomes unresponsive and can only be recovered by force closing.
This is 100% reproducible and affects all fullScreenModal screens regardless of content — confirmed on multiple screens with completely different components (one with heavy Reanimated usage, one with none).
Reproduction
Environment:
- react-native: 0.83.1
- react-native-screens: ~4.22.0
- expo-router: ~55.0.0-preview.7 (Expo SDK 55)
- iOS Simulator, New Architecture (Fabric) enabled
- Platform: iOS only
Steps:
- Create a Stack navigator with a screen using
presentation: 'fullScreenModal'andgestureEnabled: false - Navigate to that screen
- Call
router.dismiss()(or any navigation action that dismisses the modal) - Result: App freezes — UI thread hangs indefinitely
Workaround: Switching from fullScreenModal to card, modal, or transparentModal eliminates the freeze entirely. Only fullScreenModal (which uses UIModalPresentationFullScreen natively) triggers the bug.
Minimal layout example
// _layout.tsx
<Stack>
<Stack.Screen name="index" />
<Stack.Screen
name="my-modal"
options={{
presentation: 'fullScreenModal',
gestureEnabled: false,
headerShown: false,
}}
/>
</Stack>// my-modal.tsx
import { useRouter } from 'expo-router';
import { Button, View } from 'react-native';
export default function MyModal() {
const router = useRouter();
return (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<Button title="Dismiss" onPress={() => router.dismiss()} />
</View>
);
}Analysis
The freeze appears to be a race condition in the native UIModalPresentationFullScreen dismissal lifecycle on Fabric. When dismissViewControllerAnimated: completes, the Fabric shadow tree reconciliation and screen unmounting seem to conflict, causing the JS thread to hang.
Other presentation types (card, modal, transparentModal) use different native presentation paths (UIModalPresentationPageSheet, etc.) and do not trigger this issue.
Related Issues
- RN 0.80 unstable modal and app crash #2984 — RN 0.80+ unstable modal + "Attempt to recycle a mounted view" on Fabric
- [iOS] When modals are opened in two different stacks, then closing all modals freezes the screen #2988 — Modal freeze in stacks on Fabric
- iOS: RCTComponentViewRegistry: Attempt to recycle a mounted view when navigating inside tab stack while removing multiple screens #3263 — Recycle mounted view crash in screen lifecycle
- IOS Modal causing glitches and crashs when using exiting animation inside it #2545 — Reanimated exiting animations + screens interaction (ruled out — removing all animations did not fix this)