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

Expo Router vs React Navigation: Cum configurezi nested tabs și când merită migrarea

De Adrian Voicu, 2 iul. 2026 · 16 vizualizări · 3 like-uri

Postat 2 iul. 2026
typescript
import { Stack } from 'expo-router';

export default function ProfileLayout() {
  return ( 
    <Stack
      screenOptions={{
        headerStyle: { backgroundColor: '#f4511e' },
        headerTintColor: '#fff',
        headerTitleStyle: { fontWeight: 'bold' },
      }}
    >
      <Stack.Screen 
        name="index" 
        options={{ title: 'Profilul Meu' }} 
      />
      <Stack.Screen 
        name="settings" 
        options={{ title: 'Setări Cont', presentation: 'card' }} 
      />
    </Stack>
  );
}

Am trecut recent un proiect de mobil de la clasicul React Navigation la Expo Router v3 și mi-am cam prins urechile în structura de foldere. Dacă ai o aplicație cu tab-uri și ecrane imbricate (nested), migrarea asta îți poate salva zeci de linii de boilerplate sau, din contră, îți poate aduce dureri de cap. Hai să vedem când merită efortul și cum așezi fișierele alea să nu o iei razna.

Când merită să faci trecerea?

Am avut cazul unui proiect cu vreo 12.000 de utilizatori activi unde navigația era scrisă clasic. Totul era configurat imperativ într-un singur fișier mamut de vreo 600 de linii de cod. Migrarea la Expo Router ne-a redus codul de configurare cu aproape 35% și am scăpat definitiv de mentenanța manuală a tipurilor de TypeScript pentru rute.

Dar hai să fim sinceri cu trade-off-urile. Expo Router e genial dacă ai nevoie de deep linking out-of-the-box (primești URL-uri automat pentru fiecare ecran) și dacă vrei o structură curată, bazată pe foldere, similară cu Next.js.

În schimb, dacă ai o logică de business foarte dinamică, unde rutele trebuie generate condiționat în funcție de rolul utilizatorului primit din API înainte de randarea navigației, file-based routing devine un ghimpe în coastă. Te vei trezi că te lupți cu redirect-uri obositoare în useEffect-uri sau în middleware-uri improvizate.

Structura de Tab-uri și Stack-uri imbricate

Cea mai mare problemă de care m-am lovit a fost imbricarea unui Stack în interiorul unui Tab. De exemplu, ai un tab de "Profil" (Profile), dar din el vrei să navighezi către un ecran de "Setări" (Settings) care să se comporte ca un push pe stack, dar să păstreze (sau să ascundă) tab bar-ul de jos.

Pentru asta, convenția de foldere din Expo Router trebuie respectată cu sfințenie. Folosim grupuri de rute cu paranteze rotunde (tabs) ca să nu influențeze URL-ul final.

Structura de directoare recomandată arată cam așa:

app/
├── _layout.tsx          <-- Root Stack (Modals, Auth guard)
└── (tabs)/
    ├── _layout.tsx      <-- Configurare Tab.Navigator
    ├── index.tsx        <-- Ecranul Home (Tab 1)
    └── profile/
        ├── _layout.tsx  <-- Configurare Stack.Navigator intern
        ├── index.tsx    <-- Ecranul principal de Profil
        └── settings.tsx <-- Ecranul de Setări (nested)

Cum configurezi sub-stack-ul de profile

În loc să scrii zeci de linii de navigatori asociați manual, în app/(tabs)/profile/_layout.tsx configurezi doar comportamentul stack-ului local. Expo Router se ocupă de legarea lui automată la tab-ul părinte.

În fișierul de configurare al tab-urilor principale (app/(tabs)/_layout.tsx), vei mapa doar directorul profile ca fiind un singur tab, chiar dacă el în spate conține un întreg stack de ecrane. Comportamentul este extrem de curat și modular.

Dacă ai deja o aplicație mare și stabilă pe React Navigation clasic, nu te arunca la migrare doar de dragul hype-ului. Efortul de refactorizare a layout-urilor imbricate s-ar putea să nu justifice cele câteva zeci de linii de cod economisite. Însă, pentru orice proiect nou, Expo Router e deja alegerea implicită de la care nu m-aș mai abate.

Voi ce folosiți pe proiectele curente de React Native? V-ați lovit de limitări la structurile complexe de directoare în Expo Router?

Răspunsuri 0

Se încarcă răspunsurile…

Loghează-te pentru a răspunde

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