I'm using React Native with expo-router and trying to implement a modal flow that includes multiple screens (e.g. a step-by-step form or selection process). The idea is:
The modal can be opened from different parts of the app
Inside the modal, I navigate between a few screens (e.g. selection → form → confirmation)
Once the user saves or completes the task, I want to programmatically close the modal
If the user presses "Cancel" or saves successfully, the modal should be dismissed
I'm currently opening the modal using a Link or router.push('/(modals)/my-modal'), and the layout is structured like this:
app/
_layout.tsx
(tabs)/
...
(modals)/
_layout.tsx ← Modal stack layout
my-modal/
index.tsx ← First screen in the modal
step-two.tsx ← Second screen
confirmation.tsx ← Final step (calls API)
I use a Stack inside (modals)/_layout.tsx like this:
export default function ModalLayout() {
return (
<Stack screenOptions={{ presentation: 'modal' }} />
);
}
Inside the modal flow, I navigate with router.push(...) and everything works.
Problem: Once the flow completes (e.g. after a successful API call), I want to close the whole modal, regardless of how deep I am in the modal stack.
However:
router.dismiss() just does a goBack() and doesn’t close the whole modal
router.back() same
I can't detect reliably if I'm inside a modal (useNavigationState().type returns "stack")
What is the correct way to close a modal flow (with internal navigation) programmatically once the job is done (e.g. API call succeeds)?