expo / router

[ARCHIVE]: Expo Router has moved to expo/expo -- The File-based router for universal React Native apps

Home Page:https://docs.expo.dev/routing/introduction/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Expo Router v2 mounting a route twice

shessafridi opened this issue · comments

commented

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

https://github.com/shessafridi/expo-router-bug

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