react-navigation / react-navigation

Routing and navigation for your React Native apps
https://reactnavigation.org
23.28k stars 4.97k forks source link

[iOS] NavigationContainer onReady is called on unmount and never called after foregrounding #11068

Closed AlixH closed 1 year ago

AlixH commented 1 year ago

Current behavior

I have a NavigationContainer wrapping other nested containers. I am trying to dispatch navigation actions when opening a notification. To be sure that the navigation container is ready, I am dispatching the navigation actions inside the onReady prop callback. When I put the app to backround, the onReady prop callback is called Then, I tap a notification, the app is foregrounded, the navigation container is not ready, and the onReady callback never get fired until I put the app to background again

Expected behavior

I expect the onReady prop callback to be called when the app is in the foreground/being foregrounded. And even if it is called when backgrounding the app, I expect at least the navigation to be ready when foregrouding the app again

Root component code:

export default class App extends React.Component<Props, State> {
  public state: State;
  public props: Props;
  public centralServerProvider: CentralServerProvider;
  public notificationManager: NotificationManager;
  public deepLinkingManager: DeepLinkingManager;
  private appVersion: CheckVersionResponse;
  private location: LocationManager;
  private themeSubscription: NativeEventSubscription;
  private navigationRef: React.RefObject<NavigationContainerRef<ReactNavigation.RootParamList>>;

  public constructor(props: Props) {
    super(props);
    this.navigationRef = React.createRef();
    this.state = {
      switchTheme: false,
      navigationState: null,
      showAppUpdateDialog: false
    };
  }

  public async componentDidMount() {
    console.log('mount App');
    // Get the central server
    this.centralServerProvider = await ProviderFactory.getProvider();

    // Set up deep linking
    this.deepLinkingManager = DeepLinkingManager.getInstance();
    this.deepLinkingManager?.initialize(this.navigationRef?.current, this.centralServerProvider);
    // Activate Deep links
    this.deepLinkingManager.startListening();

    // Set up notifications
    this.notificationManager = NotificationManager.getInstance();
    this.notificationManager.setCentralServerProvider(this.centralServerProvider);
    this.centralServerProvider.setNotificationManager(this.notificationManager);
    await this.notificationManager?.initialize(this.navigationRef?.current);
    await this.notificationManager.start();
  }

  public componentWillUnmount() {
      console.log('UNMOUNTING ROOT');
    this.deepLinkingManager?.stopListening();
    this.notificationManager?.stop();
  }

  public render() {
    const { switchTheme, showAppUpdateDialog } = this.state;
   <SafeAreaProvider>
        <NavigationContainer
          onReady={() => this.onReady()} // <-- This is called when putting the app to background, and never after foregrouding
          ref={this.navigationRef}
          onStateChange={(newState) => this.setState({navigationState: newState})}
          initialState={this.state.navigationState}
             >
          <rootStack.Navigator initialRouteName="AuthNavigator" screenOptions={{ headerShown: false }}>
            <rootStack.Screen name="AuthNavigator" children={createAuthNavigator} />
            <rootStack.Screen name="AppDrawerNavigator" children={createAppDrawerNavigator} />
          </rootStack.Navigator>
        </NavigationContainer>
      </SafeAreaProvider>
  }

  private onReady(): void {
    void hide({ fade: true });
    this.notificationManager?.performPendingNavigationActions(); // <-- Dispatch pending navigation actions
  }
}

Platform

Packages

Environment

package version
@react-navigation/native 6.0.14
@react-navigation/drawer 6.5.1
@react-navigation/material-bottom-tabs 6.2.5
@react-navigation/stack 6.3.5
react-native-safe-area-context 4.4.1
react-native-screens 3.18.2
react-native-gesture-handler 2.8.0
react-native-reanimated 2.13.0
react-native 0.70.6
node 16.13.0
npm or yarn 9.1.2
github-actions[bot] commented 1 year ago

Hey! Thanks for opening the issue. The issue doesn't seem to contain a link to a repro (a snack.expo.dev link, a www.typescriptlang.org/play link or link to a GitHub repo under your username).

Can you provide a minimal repro which demonstrates the issue? Please try to keep the repro as small as possible and make sure that we can run it without additional setup.

A repro will help us debug the issue. The issue will be closed automatically after a while if you don't provide a repro.

github-actions[bot] commented 1 year ago

Couldn't find version numbers for the following packages in the issue:

Can you update the issue to include version numbers for those packages? The version numbers must match the format 1.2.3.

The versions mentioned in the issue for the following packages differ from the latest versions on npm:

Can you verify that the issue still exists after upgrading to the latest versions of these packages?

github-actions[bot] commented 1 year ago

Hello 👋, this issue has been open for more than a month without a repro or any activity. If the issue is still present in the latest version, please provide a repro or leave a comment within 7 days to keep it open, otherwise it will be closed automatically. If you found a solution or workaround for the issue, please comment here for others to find. If this issue is critical for you, please consider sending a pull request to fix it.

AlixH commented 1 year ago

My issue disappeared when I removed conditional rendering of my root component's content

github-actions[bot] commented 1 year ago

Hey! This issue is closed and isn't watched by the core team. You are welcome to discuss the issue with others in this thread, but if you think this issue is still valid and needs to be tracked, please open a new issue with a repro.

Dimon70007 commented 1 week ago

My issue disappeared when I removed conditional rendering of my root component's content

Thank you. It helps me a lot. I moved SafeAreaProvider inside of NavigationContainer because of SafeAreaProvider has conditional rendering its children depends on insets state

github-actions[bot] commented 1 week ago

The versions mentioned in the issue for the following packages differ from the latest versions on npm:

Can you verify that the issue still exists after upgrading to the latest versions of these packages?

github-actions[bot] commented 1 week ago

Hey @AlixH! Thanks for opening the issue. It seems that the issue doesn't contain a link to a repro.

The best way to get attention to your issue is to provide an easy way for a developer to reproduce the issue.

You can provide a repro using any of the following: