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

_layout inside a (tabs) folder throws error in navigation and gives me a blank screen

sofilay opened this issue · comments

Which package manager are you using? (Yarn is recommended)

yarn

Summary

Hello!

I'm ussing:
"expo-router": "2.0.0"
"expo": "~49.0.5"
"react-native": "0.72.3"

I have a strange behavior in routing. I want to create a bottom bar navigation.
Inside my app folder is structured as follows:

Captura de pantalla 2023-08-16 a la(s) 17 14 32

Any time I want to create a _layout so I create the tabs inside (tabs) throws me this error:

Do you have a screen named 'home/index'?

and then the screen goes blank. I do have an index inside the home folder and if I delete that _layout.tsx the redirection works.
Anyone with the same problem?

Minimal reproducible example

// app/index.tsx

import { Redirect } from 'expo-router';
import React from 'react';
import { SafeAreaView } from 'react-native';

const EntryPoint = () => {
    return (
      <SafeAreaView style={{flex: 1 }}>
        <Redirect href={'/home'} />
      </SafeAreaView>
    );
}

export default EntryPoint;

// app/_layout.tsx

import React, { useCallback } from 'react';
import { View } from 'react-native';
import { Slot, SplashScreen, Stack } from 'expo-router';
import {
  QueryClient,
  QueryClientProvider,
} from '@tanstack/react-query'
import { useFonts } from 'expo-font';

SplashScreen.preventAutoHideAsync();

const queryClient = new QueryClient()

const RootLayout = () => {
  const [fontsLoaded, fontError] = useFonts({
    'Recoleta-Regular': require('../common/assets/fonts/recoleta/Recoleta-Regular.ttf'),
    'Recoleta-Bold': require('../common/assets/fonts/recoleta/Recoleta-Bold.ttf'),
    'Recoleta-Medium': require('../common/assets/fonts/recoleta/Recoleta-Medium.ttf'),
    'Recoleta-SemiBold': require('../common/assets/fonts/recoleta/Recoleta-SemiBold.ttf'),
    'WorkSans-Regular': require('../common/assets/fonts/workSans/WorkSans-Regular.ttf'),
    'WorkSans-Medium': require('../common/assets/fonts/workSans/WorkSans-Medium.ttf'),
    'WorkSans-Bold': require('../common/assets/fonts/workSans/WorkSans-Bold.ttf'),
    'WorkSans-Light': require('../common/assets/fonts/workSans/WorkSans-Light.ttf'),
    'WorkSans-SemiBold': require('../common/assets/fonts/workSans/WorkSans-SemiBold.ttf'),
  });

  const onLayoutRootView = useCallback(async () => {
    if (fontsLoaded) {
      await SplashScreen.hideAsync();
    }
  }, [fontsLoaded]);

  if (!fontsLoaded) {
    return <Slot/>
  }
  

  return (
    <QueryClientProvider client={queryClient}>
        <View style={{ flex: 1 }} onLayout={onLayoutRootView}>
          <Stack
            initialRouteName="index"
            screenOptions={{headerShown: false}}
          />
        </View>
    </QueryClientProvider>
  );
}

export default RootLayout

export const unstable_settings = {
  initialRouteName: 'index',
};

// app/(tabs)/_layout.tsx

import { Tabs } from "expo-router"

export default function TabsLayout() {
    return (
    <Tabs>
        <Tabs.Screen
          name="home"
        />
      </Tabs>
    );
  }

// app/(tabs)/home/index.tsx

import { Stack } from 'expo-router'
import React from 'react'
import { View, Text } from 'react-native'

const Home = () => {
  return (
    <>
      <View style={{flex: 1, justifyContent: 'center', alignItems: 'center' }}>
        <Text>Home</Text>
      </View>
    </>
  )
}

export default Home

same here

Yeah I had the same issue. It seems to work if you add a _layout.tsx in each tab's subfolder like:

// app/(tabs)/home/_layout.tsx

import {Stack} from "expo-router/stack";

export default function HomeLayout() {
  return (
    <Stack>
      <Stack.Screen name="index" />
    </Stack>
  )
}

In app/_layout.tsx add (tab) to stack screen to register it

 // app/_layout.tsx
...

return (
    <QueryClientProvider client={queryClient}>
        <View style={{ flex: 1 }} onLayout={onLayoutRootView}>
          <Stack
            initialRouteName="index"
            screenOptions={{headerShown: false}}
          >
               <Stack.Screen name="index" />
               <Stack.Screen name="register" />
               <Stack.Screen name="(tabs)" /> // <---
          </Stack>
        </View>
    </QueryClientProvider>
  );

In app/_layout.tsx add (tab) to stack screen to register it

 // app/_layout.tsx
...

return (
    <QueryClientProvider client={queryClient}>
        <View style={{ flex: 1 }} onLayout={onLayoutRootView}>
          <Stack
            initialRouteName="index"
            screenOptions={{headerShown: false}}
          >
               <Stack.Screen name="index" />
               <Stack.Screen name="register" />
               <Stack.Screen name="(tabs)" /> // <---
          </Stack>
        </View>
    </QueryClientProvider>
  );

I did it! but doesn't work for me :(

I solved it commenting this lines in the app/index:

export const unstable_settings = {
   initialRouteName: 'index',
 };

And I added a _layout.tsx inside the app/(tabs)/home components with this code:

import React from 'react'
import { Stack } from 'expo-router'

const StackLayout = () => {
  return (
    <Stack>
        <Stack.Screen name='index' options={{
            headerTitle: 'Home Screen'
        }}/>
    </Stack>
  )
}

export default StackLayout

Thank you for the help!