eduardweb.
Navigație & StateIntermediar#react-native#expo-router#react-navigation#mobile-dev

Expo Router vs React Navigation: Când merită migrarea și cum legi Tab-urile de Stacks

De Vlad Stancu, 29 iul. 2026 · 11 vizualizări · 3 like-uri

Postat 29 iul. 2026
typescript
// 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 tab
  • app/(tabs)/explore/index.tsx -> Ecranul principal din Explore
  • app/(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

  1. Autentificarea și ecranele protejate: Nu folosi redirecționări în useEffect pentru ecranul de login. Folosește useSegments ș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.
  2. State-ul de tab la apăsare dublă: În React Navigation aveai popToTop out-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 evenimentul tabPress î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?

Răspunsuri 0

Se încarcă răspunsurile…

Loghează-te pentru a răspunde

Doar membrii comunității pot lăsa comentarii.