Expo Router v2 mounting a route twice
shessafridi opened this issue · comments
Which package manager are you using? (Yarn is recommended)
npm
Summary
Expo router V2 in mounting routes twice when navigating to an outside route from a tabs screen when the tabs screen and the outside screen is in a group, this issue is not present in v1.
In the example when navigating from /my-account
to /address
the address/index.tsx
component is mounted twice as indicated by
useEffect(() => { console.log('Address Mount'); }, []);
In the address/index.tsx
file, this is a big issue as it also plays the routing animation twice on Android.
Removing the (first-level)
group will fix the issue but in my use case I need it.
Example app folder structure:
app
│ index.tsx
│ _layout.tsx
│
└───(first-level)
│ _layout.tsx
│
├───(tabs)
│ home.tsx
│ my-account.tsx
│ _layout.tsx
│
└───address
index.tsx
_layout.tsx
Minimal reproducible example
This example has a commit called "expo 49" which has the issue, and another commit called "No Issue on Expo 48" which has the project downgraded to expo router v1 with no code change
Same here
Also experiencing the same issue. Thought I was doing routing incorrectly.
yeah same problem here
This is due to a bug in React Navigation where passing the seemingly correct navigation state will cause the stack to invalidate the second screen and re-mount it. You can work around this by using React Navigation to "push" the destination screen, the caveat being that usePathname
and related URL will not be correct. Here's an updated app/(first-level)/(tabs)/my-account.tsx
that navigates to the screen without re-rendering.
import { View, Text } from "react-native";
import React from "react";
import { Link, useNavigation } from "expo-router";
type Props = {};
const MyAccountPage = (props: Props) => {
const navigation = useNavigation();
return (
<View>
<Text>MyAccountPage</Text>
{/* Correct navigation + URL, but re-renders */}
<Link href="/address">Address</Link>
{/* Correct navigation, single render, but incorrect URL and transition. */}
<Text
onPress={() => {
navigation.push("address");
}}
>
Address with React Nav
</Text>
</View>
);
};
export default MyAccountPage;
Also worth mentioning that nesting Stack -> Slot -> Stack
may lead to problems if the nested stacks can conform to the same push events. Stacks aren't analogous to the web, if you push a page, the resolution will bubble up and may be handled in a way that makes sense technically but doesn't feel ergonomic to the developer or user.
A fix has been published in expo-router@2.0.4
A fix has been published in
expo-router@2.0.4
thank you!
@EvanBacon In 2.0.9,
- Route is mounting twice
- And also mounting when you navigate to an other route
@oliviercperrier Please create a new issue with a reproducible demo. We cannot assist you if you don't provide any information