Repository: expo/router

Issue #430: The 'navigation' object has not been initialized when trying to render <View> in root layout instead of <Slot /> or <Stack>
Created: 2023-03-27T07:10:09Z
Summary
I am trying to set up some authentication using expo-router. So, I want to show a loading spinner while the auth data is fetching (ideally I wouldn't need this and could just keep the SplashScreen up but that's another story completely).
Anyway, this is my root layout
import "react-native-gesture-handler"; // must be imported in root layout
import FontAwesome from "@expo/vector-icons/FontAwesome";
import { DarkTheme, DefaultTheme, ThemeProvider } from "@react-navigation/native";
import { useFonts } from "expo-font";
import { Slot, SplashScreen, Stack, useFocusEffect, usePathname, useRouter, useSegments } from "expo-router";
import { useEffect, useState } from "react";
import { ActivityIndicator, useColorScheme } from "react-native";
import { QueryClientProvider } from "@tanstack/react-query";
import { TRPC_BASE_URL, queryClient, trpcClient, trpcQuery } from "../config/api";
import { AuthProvider, useAuth } from "../config/auth";
import { View } from "../components/Themed";

export {
  // Catch any errors thrown by the Layout component.
  ErrorBoundary,
} from "expo-router";

export const unstable_settings = {
  // Ensure that reloading on `/modal` keeps a back button present.
  initialRouteName: "(tabs)",
};

export default function RootLayout() {
  const [loaded, error] = useFonts({
    SpaceMono: require("../assets/fonts/SpaceMono-Regular.ttf"),
    ...FontAwesome.font,
  });

  // Expo Router uses Error Boundaries to catch errors in the navigation tree.
  useEffect(() => {
    if (error) throw error;
  }, [error]);

  return (
    <>
      {/* Keep the splash screen open until the assets have loaded. In the future, we should just support async font loading with a native version of font-display. */}
      {!loaded && <SplashScreen />}
      {loaded && <AppRoot />}
    </>
  );
}

function AppRoot() {
  return (
    <trpcQuery.Provider client={trpcClient} queryClient={queryClient}>
      <QueryClientProvider client={queryClient}>
        <AuthProvider>
          <RootLayoutNav />
        </AuthProvider>
      </QueryClientProvider>
    </trpcQuery.Provider>
  );
}

function RootLayoutNav() {
  const colorScheme = useColorScheme();
  const { isLoading } = useAuth();

  if (isLoading) {
    return (
      <View style={{ flex: 1, justifyContent: "center", alignItems: "center" }}>
        <ActivityIndicator size="large" />
      </View>
    );
  }

  return (
    <ThemeProvider value={colorScheme === "dark" ? DarkTheme : DefaultTheme}>
      <Stack>
        <Stack.Screen name="(tabs)" options={{ headerShown: false }} />
        <Stack.Screen name="modal" options={{ presentation: "modal" }} />
      </Stack>
    </ThemeProvider>
  );
}
For some reason, the code in the RootLayoutNav component that is shown below leads to the error The 'navigation' object hasn't been initialized yet. This might happen if you don't have a navigator mounted, or if the navigator hasn't finished mounting. See https://reactnavigation.org/docs/navigating-without-navigation-prop#handling-initialization for more details.
  if (isLoading) {
    return (
      <View style={{ flex: 1, justifyContent: "center", alignItems: "center" }}>
        <ActivityIndicator size="large" />
      </View>
    );
  }
Not sure why this is happening. I assume it is because the root layout expects to render a Stack or a Slot or something, but not too sure if I'm doing something wrong or if there is a bug within expo-router
Minimal reproducible example
I added some code above but I can make a repo if necessary.

Duplicate issue #817: Navigation not possible on root component
Created: 2023-07-29T15:53:16Z
Which package manager are you using? (Yarn is recommended)
npm
Summary
After upgrading to expo router v2 I get the following when starting the app
Error: Attempted to navigate before mounting the Root Layout component. Ensure the Root Layout component is rendering a Slot, or other navigator on the first render.
_layout.tsx
import { NavigationThemeProvider } from '@theme'
import { useFonts } from 'expo-font'
import { Slot } from 'expo-router'
import * as SplashScreen from 'expo-splash-screen'

import { ReactElement, useEffect } from 'react'

import { ThemeProvider } from '@rneui/themed'
import { QueryClient, QueryClientProvider } from '@tanstack/react-query'

import { theme } from './lib/theme/theme'

SplashScreen.preventAutoHideAsync()

const queryClient = new QueryClient()

export default function Layout(): ReactElement | null {
  const [fontsLoaded] = useFonts({
    'Poppins-Bold': require('./lib/assets/fonts/Poppins/Poppins-Bold.ttf'),
    'Poppins-Regular': require('./lib/assets/fonts/Poppins/Poppins-Regular.ttf'),
    'Poppins-SemiBold': require('./lib/assets/fonts/Poppins/Poppins-SemiBold.ttf'),
  })

  useEffect(() => {
    if (fontsLoaded) SplashScreen.hideAsync()
  }, [fontsLoaded])

  if (!fontsLoaded) {
    return null
  }

  return (
    <ThemeProvider theme={theme}>
      <NavigationThemeProvider>
        <QueryClientProvider client={queryClient}>
          <Slot />
        </QueryClientProvider>
      </NavigationThemeProvider>
    </ThemeProvider>
  )
}
index.tsx
import { Redirect } from 'expo-router'

import React, { ReactElement } from 'react'

export default function App(): ReactElement {
  return <Redirect href="root/prosumer/drawer/tabs/dashboard" />
}
The issue here is the redirect in index.tsx. Is there any way I can wait for react navigation to be initialized before performing the redirect?
Minimal reproducible example
See above

Closing comment (2023-07-29T15:55:31Z): Probably related to #430.