A sensible router for Expo.
When you have an expo app setup like the following and go via redirects / -> /event/index -> /event/[event] -> /user/profile and you try to go back, you will get thrown to /, because switching between routers causes the history to reset.
However, in this case this is not what you want, and I'd expect to go back to the previous screen, even if that screen is not in the same router.
- DrawerRouter (
/)- StackRouter (
/event)- StackScreen (
/event/index) - StackScreen (
/event/[event])
- StackScreen (
- StackRouter (
/user)- StackScreen (
/user/index) - StackScreen (
/user/profile)
- StackScreen (
- StackRouter (
Using this InhouseRouter component, I track the history (page + params) separately and make redirects work as one would expect.
You can just drop this router.tsx file into your project's components folder and adjust it as needed to integrate with your components.
It comes with the replacements for expo-router's functions useRouter and <Redirect /> that you will need your code to use exclusively instead of expo-router's. All pages that have the native headerBack shown you want to substitute the InhouseHeaderBack for that to use this router as well.
Other expo-router functions like usePathname will still work as expected.
Additionally, you get the useBlocked hook you can use in pages you want to block or override the back button.
You can also apparantly consolidate all StackRoutes into a single DrawerScreen. This way, you are not switching DrawerScreens and the root StackRouter does not get discarded.
Curiously, even if you switch to /, which is not the same DrawerScreen as /_/, the StackRouter does not get unloaded.
However, if you have no /index.tsx entirely and only a /_/index.tsx, the Drawer layout does not even get applied.
All in all, this "solution" is more of a workaround, but may be slightly less jank than wrapping the router.
- DrawerRouter (
/)- DrawerScreen (
/) - StackRouter (
/_/)- StackScreen (
/_/event/index) - StackScreen (
/_/event/[event]) - StackScreen (
/_/user/index) - StackScreen (
/_/user/profile)
- StackScreen (
- DrawerScreen (
or
- DrawerRouter (
/)- DrawerScreen (
/) - StackRouter (
/_/)- StackRouter (
/_/event)- StackScreen (
/_/event/index) - StackScreen (
/_/event/[event])
- StackScreen (
- StackRouter (
/_/user)- StackScreen (
/_/user/index) - StackScreen (
/_/user/profile)
- StackScreen (
- StackRouter (
- DrawerScreen (