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

Expo Router vs React Navigation: Când merită migrarea și cum faci Tab + Stack nested

De Cosmin Rotaru, 10 aug. 2026 · 5 vizualizări · 2 like-uri

Postat acum 6 zile
typescript
import { Stack } from 'expo-router';

// app/(tabs)/explore/_layout.tsx
// Acest layout creează un Stack nativ doar în interiorul tab-ului Explore
export default function ExploreLayout() {
  return (
    <Stack
      screenOptions={{
        headerStyle: { backgroundColor: '#0f172a' },
        headerTintColor: '#fff',
        headerTitleStyle: { fontWeight: '600' },
      }}
    >
      <Stack.Screen
        name="index"
        options={{ title: 'Explorează' }}
      />
      <Stack.Screen
        name="details"
        options={{ 
          title: 'Detalii Produs', 
          headerBackTitle: 'Înapoi' 
        }}
      />
    </Stack>
  );
}

Am trecut recent o aplicație cu vreo 12k utilizatori activi lunar de la clasicul React Navigation la Expo Router v3. Decizia n-a fost ușoară, mai ales că aveam deja o grămadă de boilerplate scris pe navigația veche care pur și simplu își făcea treaba. Dacă te bătorești cu dilema asta pe un proiect curent, îți zic direct ce am câștigat, unde ne-am lovit și cum rezolvi cel mai frecvent scenariu: tab-uri cu stack-uri nested.

De ce ai vrea (sau nu) să faci trecerea?

React Navigation e un cal de bătaie pe care îl știm toți. Configurezi navigatoarele imperativ, arunci niște Stack.Navigator și Tab.Navigator prin fișiere, iar deep linking-ul devine repede un coșmar dacă ai mai mult de trei pagini. Am pierdut la un moment dat vreo 2 zile doar configurând schema de URL-uri la un proiect anterior și tot crăpa pe Android pe anumite edge case-uri.

Expo Router schimbă complet foaia. E file-based routing, fix conceptul pe care îl știi din Next.js sau Remix. Câștigul masiv? Deep linking nativ, automat, plus rute tipizate out-of-the-box fără să mai scrii tu un RootStackParamList de 200 de linii pe care uiți să-l actualizezi.

Dar există un trade-off clar. La o aplicație veche și mare, refactorizarea directoarelor te costă mult timp. De asemenea, dacă ai navigatoare custom foarte ciudate sau animații ultra-specifice între ecrane non-standard, abstracția Expo Router te poate încurca puțin, fiindcă trebuie să treci prin wrapper-ele lor înainte să ajungi la instanța nativă de React Navigation.

Cum configurezi Tab + Stack nested în Expo Router

Cea mai mare confuzie pe care o văd la devii care trec la Expo Router e structura folderelor când ai o navigație cu tab-uri jos, iar fiecare tab trebuie să aibă propriul lui stack independent (de exemplu: Tab Explore -> Lista -> Detalii produs).

În React Navigation apelai createBottomTabNavigator și în interiorul fiecărui tab puneai un createNativeStackNavigator. În Expo Router faci totul prin directoare și fișiere _layout.tsx speciale.

Structura curată de directoare arată așa:

  • app/_layout.tsx (Root stack - de obicei gestionează auth/modale)
  • app/(tabs)/_layout.tsx (Definirea tab-urilor de jos)
  • app/(tabs)/index.tsx (Primul tab, ex: Feed)
  • app/(tabs)/explore/_layout.tsx (Stack-ul intern din tab-ul Explore)
  • app/(tabs)/explore/index.tsx (Lista din Explore)
  • app/(tabs)/explore/details.tsx (Ecranul de detalii)

Numele de folder cu paranteze rotunde (tabs) îi spune routerului că acel folder este un group — adică oferă un layout comun fără să adauge un segment suplimentar în URL-ul aplicației.

Ce am învățat din migrare

Am economisit cam 35% din liniile de cod dedicate navigației și am scăpat definitiv de bug-urile ciudate la notificările push. Înainte, dacă userul apăsa pe un push notification când aplicația era ucisă de OS, aveam șanse mari ca React Navigation să nu restabilească corect starea stivei. Cu file-based routing, îi dai doar calea /explore/123 și routerul știe exact să instanțieze stack-ul în spatele tab-ului respectiv.

Dacă începi un proiect nou azi, nu văd niciun motiv rațional să nu mergi direct pe Expo Router. În schimb, dacă ai o aplicație legacy complexă care funcționează și nu depinzi masiv de deep linking, las-o așa. Nu repara ce nu e stricat.

Voi ce folosiți pe producție în aplicațiile curente? Ați întâmpinat blocaje severe cu file-based routing pe React Native?

Răspunsuri 0

Se încarcă răspunsurile…

Loghează-te pentru a răspunde

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