// app/(tabs)/_layout.tsx
import { Tabs } from 'expo-router';
import { Ionicons } from '@expo/vector-icons';
export default function TabsLayout() {
return (
<Tabs screenOptions={{ headerShown: false }}>
<Tabs.Screen
name="index"
options={{
title: 'Acasă',
tabBarIcon: ({ color }) => <Ionicons name="home" size={24} color={color} />,
}}
/>
<Tabs.Screen
name="explore"
options={{
title: 'Explorează',
tabBarIcon: ({ color }) => <Ionicons name="compass" size={24} color={color} />,
}}
/>
</Tabs>
);
}Am refăcut recent navigația pentru o aplicație de livrări cu peste 20k utilizatori activi, trecând de la React Navigation v6 la Expo Router 3. Miza a fost simplă: aveam nevoie de deep linking nativ fără să mai scriu 200 de linii de config doar ca să mapez URL-uri de notificări push. Dacă merită migrarea și pentru proiectul tău, depinde direct de câtă flexibilitate dinamică ceri de la rute.
Când are sens migrarea (și când să zici pas)
Expo Router nu înlocuiește React Navigation, ci este un wrapper opinionat peste el, aducând paradigma de file-based routing din Next.js pe mobil. Asta înseamnă că structura ta de foldere din app/ devine automat harta aplicației.
Proiectul cu 20k useri de care menționam avea o problemă masivă: de fiecare dată când trimiteam o notificare push cu un link de genul app://order/123/track, configurarea din React Navigation se dădea peste cap dacă utilizatorul nu era deja autentificat sau dacă deschidea aplicația din "cold start". Cu Expo Router, deep linking-ul este inclus din cutie. Am economisit cam 30% din timpul de mentenanță pe zona de rutare și am șters sute de linii de boilerplate.
Dar există un trade-off sincer. Expo Router este excelent când rutele tale sunt statice și predictibile. În schimb, dacă ai un flux de onboarding super ciudat, unde ecranele se reordonează dinamic la runtime pe baza unui feature flag primit de la backend, file-based routing devine un chin. Va trebui să faci hack-uri cu router.replace și redirecționări în cascadă care pot crea flicker vizual.
Structura Tab + Stack imbricat: cum o configurezi corect
Cea mai frecventă bătaie de cap apare când vrei să ai o bară de Tab-uri jos, iar fiecare Tab să aibă propriul lui Stack independent de ecrane.
În React Navigation clasic, defineai <Tab.Navigator> și în interior puneai <Stack.Navigator> pentru fiecare tab. În Expo Router, totul se reduce la structura de foldere și fișiere _layout.tsx.
Punctul cheie este folosirea Grupurilor de Rute (foldere cu paranteze rotunde, de exemplu (tabs)), care nu afectează URL-ul sau calea, dar permit izolarea layout-urilor.
Iată cum arată arhitectura de fișiere:
app/(tabs)/_layout.tsx-> Aici definești componenta<Tabs>app/(tabs)/index.tsx-> Primul tab (ex: Home)app/(tabs)/explore/_layout.tsx-> Stack-ul interior pentru al doilea tabapp/(tabs)/explore/index.tsx-> Ecranul principal din Exploreapp/(tabs)/explore/details.tsx-> Ecranul de detaliu împins peste Explore
Când utilizatorul navighează de la explore/index la explore/details, bara de tab-uri rămâne vizibilă jos, iar stack-ul interior se animă curat. Dacă vrei ca ecranul de detaliu să acopere și bara de tab-uri (full-screen modal), pur și simplu scoți fișierul de detaliu în afara grupului (tabs) și îl pui în root layout.
Mici capcane de care m-am lovit în producție
- Autentificarea și ecranele protejate: Nu folosi redirecționări în
useEffectpentru ecranul de login. FoloseșteuseSegmentsși un<Slot />protejat direct în_layout.tsx-ul rădăcină. Altfel, aplicația va încerca să randeze ecranul privat pentru 50ms înainte să sară la Login, creând un flash deranjant. - State-ul de tab la apăsare dublă: În React Navigation aveai
popToTopout-of-the-box. În Expo Router, dacă vrei ca la al doilea tap pe tab-ul activ să resetezi stack-ul acelui tab, trebuie să interceptezi evenimentultabPressîn opțiunile de ecran.
Dacă pornești un proiect nou azi, recomand 100% Expo Router. Dacă ai deja un app mare pe React Navigation v6 care funcționează brici și nu depinzi masiv de web sau deep links complexe, nu te arunca să migrezi doar de dragul refactoring-ului.
Voi ce folosiți pe proiectele curente? Ați făcut trecerea la Expo Router sau ați rămas pe React Navigation pur?