_layout inside a (tabs) folder throws error in navigation and gives me a blank screen
sofilay opened this issue · 5 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:
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!