Push/pop, headers y opciones de pantalla en directorios app/. Stack de expo-router es la interfaz basada en archivos de @react-navigation/native-stack - cada archivo de ruta hermana dentro de una carpeta con _layout.tsx se convierte en una pantalla de stack.
app/orders/_layout.tsx → <Stack> envuelve esta carpetaapp/orders/index.tsx → ruta inicial (fondo del stack)app/orders/[id].tsx → se impulsa cuando se navega a /orders/:idapp/orders/new.tsx → se impulsa cuando se navega a /orders/new
Expo Router registra automáticamente cada archivo de ruta como un Stack.Screen - <Stack.Screen name="..."> explícito es opcional pero recomendado para opciones
La ruta inicial es la primera pantalla coincidente en la navegación; los enlaces profundos pueden abrir [id] directamente
Los archivos hermanos comparten un historial de stack - las carpetas sin _layout.tsx heredan el navegador padre
(tabs)/_layout.tsx → Tabs (barra de tabs siempre visible)(tabs)/orders/_layout → Stack (push dentro de la tab Orders solo)
Cada tab mantiene un historial de stack independiente - cambiar entre tabs preserva el estado de stack de cada tab de forma predeterminada. Restablece stacks al cerrar sesión con router.replace o remontando la clave del navegador.
Falta _layout.tsx en una carpeta con múltiples pantallas - los hermanos pueden aplanarse inesperadamente en el stack padre. Solución: Agrega orders/_layout.tsx con <Stack /> cuando una carpeta tiene index + [id].
Nombres de pantalla duplicados de archivos de índice - orders.tsx y orders/index.tsx entran en conflicto. Solución: Elige una forma de URL por característica.
headerShown: false en el stack raíz pero esperando encabezados anidados - los stacks secundarios deben establecer headerShown: true explícitamente. Solución: Configura encabezados en el _layout.tsx anidado donde viven las pantallas.
Parpadeo de título dinámico - el título predeterminado se muestra antes de que se complete la búsqueda. Solución: Usa un título esqueleto o headerLargeTitle: false hasta que se carguen los datos; establece opciones en useEffect.
router.push después del inicio de sesión duplica la autenticación en el stack posterior - los usuarios hacen deslizar hacia atrás para iniciar sesión. Solución:router.replace('/(tabs)') después de la autenticación exitosa.
Modal sin manejo del back de Android - presentation: "modal" aún respeta el hardware back, pero los overlays personalizados podrían no hacerlo. Solución: Prueba el back de Android; prefiere rutas reales sobre overlays de posición absoluta.
El enlace profundo abre stack a mitad del árbol sin índice - /orders/99 puede omitir la pantalla de lista. Solución: Aceptable para notificaciones; usa router.back() UI de respaldo cuando el stack está vacío.
// En _layout.tsx<Stack.Screen name="login" options={{ headerShown: false }} />// O exporta desde el archivo de rutaexport const options = { headerShown: false };
Establece headerShown: false en la pantalla específica - las screenOptions padre aún pueden aplicarse a los hermanos.
¿Cómo agrego un botón derecho al encabezado?
import { Stack, router } from "expo-router";import { Pressable, Text } from "react-native";export default function EditScreen() { return ( <> <Stack.Screen options={{ headerRight: () => ( <Pressable onPress={() => router.push("/preview")}> <Text>Previsualizar</Text> </Pressable> ), }} /> {/* cuerpo de la pantalla */} </> );}
Usa headerLeft, headerRight, o headerTitle render props - misma API que React Navigation.
¿Puedo usar un componente de encabezado personalizado?
Sí - header: () => <MyHeader /> en opciones de pantalla. Prefiere encabezados del sistema de diseño para consistencia. Oculta el predeterminado con headerShown: false y renderiza el tuyo en el cuerpo de la pantalla solo cuando el encabezado del stack es insuficiente.
¿Cómo funciona el hardware back de Android?
El hardware back saca el stack actual. En la primera pantalla del stack raíz, back sale de la app (o se mueve al fondo). Prueba stacks anidados dentro de tabs - back debería sacar el detalle antes de cambiar entre tabs.
¿Cómo restablezco el stack al cerrar sesión?
import { router } from "expo-router";router.replace("/(auth)/login");
replace elimina rutas anteriores del historial. Para restablecimientos complejos, remonta el navegador con una key vinculada a userId en el layout raíz.
¿Deberían ser modales rutas o React Native Modal?
Rutas cuando el modal tiene una URL, enlace profundo, o debería aparecer en el historial de navegación. RN Modal para UI efímera sin ruta compartible. Documenta la elección del equipo en un ADR cuando aparecen ambos patrones.
¿Cómo paso datos entre pantallas de stack?
Parámetros de URL para IDs y estado superficial (params: { id })
Store global (Zustand, TanStack Query) para entidades compartidas
Evita JSON grande en parámetros - las URLs se registran y persisten en el estado de navegación
animation: "slide_from_right" | "fade" | "fade_from_bottom" | "flip" | "simple_push" | "none" en screenOptions. Los valores predeterminados de plataforma difieren - verifica en simuladores de iOS y Android.
¿Puedo anidar un stack dentro de otro stack?
Sí - app/settings/_layout.tsx puede exportar <Stack> mientras está dentro del stack raíz. Limita la profundidad a dos stacks (raíz + característica) antes de que la UX y la depuración sufran.
¿Cómo deshabilito el swipe-back en una pantalla sensible?