I'm using expo-router to set up a Tabs layout and encountered an issue; the Tabs navigation doesn't work as expected in a specific folder structure; I am using tabs navigation for my audits folder and a more global navigation using a drawer. Here's what I'm observing:
Some unique characteristics of the problematic folder(s):
Here's my audits _layout code:
import { Tabs } from 'expo-router';
import React from 'react';
import { Platform } from 'react-native';
import { HapticTab } from '@/components/HapticTab';
import { IconSymbol } from '@/components/ui/IconSymbol';
import TabBarBackground from '@/components/ui/TabBarBackground';
import { Colors } from '@/constants/Colors';
import { useColorScheme } from '@/hooks/useColorScheme';
export default function AuditsLayout() {
const colorScheme = useColorScheme();
return (
<Tabs
screenOptions={{
tabBarActiveTintColor: Colors[colorScheme ?? 'light'].tint,
headerShown: false,
tabBarButton: HapticTab,
tabBarBackground: TabBarBackground,
tabBarStyle: Platform.select({
ios: { position: 'absolute', backgroundColor: 'transparent' },
default: { backgroundColor: Colors[colorScheme ?? 'light'].background },
}),
}}>
<Tabs.Screen
name="index"
options={{
title: 'Home',
tabBarIcon: ({ color }) => <IconSymbol size={28} name="house.fill" color={color} />,
}}
/>
<Tabs.Screen
name="new"
options={{
title: 'New',
tabBarIcon: ({ color }) => <IconSymbol size={28} name="square.fill" color={color} />,
}}
/>
<Tabs.Screen
name="[id]"
options={{
title: 'Show',
tabBarShowLabel: true,
href: null,
}}
/>
</Tabs>
);
}
Here's my Base _layout code:
import {
DarkTheme,
DefaultTheme,
ThemeProvider,
} from "@react-navigation/native";
import { useFonts } from "expo-font";
import { Stack, Tabs, useRouter, useSegments } from "expo-router";
import * as SplashScreen from "expo-splash-screen";
import { StatusBar } from "expo-status-bar";
import React, { useEffect, useState } from "react";
import "react-native-reanimated";
import "../global.css";
import { i18n, initializeLocale } from "../services/localization";
import { Provider, useSelector, useDispatch } from "react-redux";
import { AppDispatch, RootState } from "@/store/redux";
import { GestureHandlerRootView } from "react-native-gesture-handler";
import { Drawer } from "expo-router/drawer";
import { DrawerToggleButton } from "@react-navigation/drawer";
import { View } from "react-native";
import { PersistGate } from "redux-persist/integration/react";
import { store, persistor } from "@/store/redux";
import ConnectionStatusIndicator from "@/components/My components/ConnectionStatusIndicator";
import { monitorConnection } from "@/store/redux/connectionSlice";
import { SafeAreaView } from "react-native-safe-area-context";
import NavigationDrawer from "@/components/My components/NavigationDrawer";
import { themes } from "@/store/redux/themeSlice";
SplashScreen.preventAutoHideAsync();
function AppContent() {
const { theme, settings } = useSelector((state: RootState) => state.theme);
const dispatch = useDispatch<AppDispatch>();
const segments = useSegments(); // Get the current route segments
const hideDrawerToggleRoutes = ["login", "password-reset", "+not-found"];
const isHiddenRoute = segments.some((segment) =>
hideDrawerToggleRoutes.includes(segment)
);
useEffect(() => {
dispatch(monitorConnection());
}, [dispatch]);
return (
<ThemeProvider value={theme === "dark" ? DarkTheme : DefaultTheme}>
<SafeAreaView className={`flex-1 ${settings.SafeAreaView}`}>
<StatusBar style={theme === "dark" ? "light" : "dark"} />
<GestureHandlerRootView className="flex-1">
{!isHiddenRoute && (
<View
className={`h-20 flex-row items-center px-4 ${settings.DrawerHeader}`}
>
<DrawerToggleButton />
<View className="ml-2">
<ConnectionStatusIndicator />
</View>
</View>
)}
<NavigationDrawer />
</GestureHandlerRootView>
</SafeAreaView>
</ThemeProvider>
);
}
export default function RootLayout() {
const [loaded] = useFonts({
SpaceMono: require("../assets/fonts/SpaceMono-Regular.ttf"),
});
useEffect(() => {
if (loaded) {
SplashScreen.hideAsync();
initializeLocale();
}
}, [loaded]);
if (!loaded) {
return null;
}
return (
<Provider store={store}>
<PersistGate loading={null} persistor={persistor}>
<AppContent />
</PersistGate>
</Provider>
);
}
After sitting on this for so long, the solution for me was to Update all my dependencies, now i dont really know what was it that solved it for me but its probably expo related.