Pylarion Logo Pylarion Logo Pylarion
MOBILE DEVELOPMENT
11 MIN READ

Creación de un Drawer con Bottom Tabs en Expo Router

Pylarion Pylarion

Pylarion

Equipo de Pylarion. Construimos software confiable donde la tecnología no puede fallar. • 13 de julio de 2026

Creación de un Drawer con Bottom Tabs en Expo Router

Creación de un Drawer con Bottom Tabs en Expo Router: Arquitectura de Navegación Avanzada para React Native

El ecosistema de desarrollo móvil con React Native ha evolucionado considerablemente en los últimos años, y con él, la complejidad de las arquitecturas de navegación que los desarrolladores deben implementar. Expo Router, construido sobre React Navigation, introduce un paradigma basado en el sistema de archivos que simplifica la organización de rutas, pero también impone ciertos desafíos técnicos cuando se trata de combinar múltiples tipos de navegadores. Uno de los patrones más demandados en aplicaciones modernas es el uso simultáneo de un Drawer Navigation —menú lateral deslizante— que envuelve a un conjunto de Bottom Tabs —pestañas inferiores—, generando una jerarquía de navegación que maximiza la accesibilidad de secciones principales sin sacrificar el espacio visual de la pantalla.

Este artículo aborda en profundidad cómo construir esta arquitectura combinada utilizando Expo Router, explorando tanto la estructura de directorios necesaria como las configuraciones críticas que garantizan una experiencia de usuario fluida, libre de conflictos de gestos y coherente con los principios de diseño de interfaces móviles modernas.

Fundamentos del Sistema de Enrutamiento Basado en Archivos de Expo Router

Expo Router adopta un enfoque declarativo para la navegación mediante la estructura del sistema de archivos, similar al enrutamiento que popularizó Next.js en el ecosistema web. Cada archivo ubicado dentro del directorio app/ representa automáticamente una ruta accesible dentro de la aplicación. Los archivos especiales como _layout.tsx cumplen el rol de envoltorios de navegación para los segmentos del directorio donde residen. Esta convención elimina la necesidad de configurar manualmente un árbol de navegadores, reduciendo la fricción en proyectos a escala, aunque exige un entendimiento preciso de cómo se anidan los layouts para evitar comportamientos inesperados en tiempo de ejecución.

Para implementar la combinación Drawer + Bottom Tabs, la estructura de directorios debe reflejar correctamente la jerarquía deseada. El Drawer actúa como el navegador raíz, mientras que los Bottom Tabs operan como un segmento hijo dentro de él. Una estructura típica sería la siguiente:

app/
├── _layout.tsx          ← Layout raíz: configura el Drawer
├── (drawer)/
│   ├── _layout.tsx      ← Configura las rutas del Drawer
│   └── (tabs)/
│       ├── _layout.tsx  ← Configura los Bottom Tabs
│       ├── index.tsx    ← Tab 1: Inicio
│       ├── explore.tsx  ← Tab 2: Explorar
│       └── profile.tsx  ← Tab 3: Perfil
├── settings.tsx         ← Ruta accesible desde el Drawer directamente

Esta disposición garantiza que el Drawer tenga visibilidad global sobre toda la aplicación, mientras que los Bottom Tabs permanecen encapsulados como una ruta específica dentro del sistema de navegación lateral. La clave está en que el archivo _layout.tsx del segmento (drawer)/ debe instanciar un componente Drawer proveniente de expo-router/drawer, que internamente utiliza @react-navigation/drawer.

Implementación del Layout del Drawer

La configuración del Drawer en Expo Router requiere la instalación previa de las dependencias necesarias. Es fundamental asegurarse de que react-native-gesture-handler y react-native-reanimated estén correctamente configurados, dado que el Drawer depende de estos paquetes para ejecutar las animaciones de deslizamiento y el reconocimiento de gestos.

npx expo install expo-router @react-navigation/drawer react-native-gesture-handler react-native-reanimated

El archivo app/(drawer)/_layout.tsx debe exportar el componente de navegación del Drawer con la configuración adecuada de cada pantalla. A continuación se muestra una implementación representativa:

import { GestureHandlerRootView } from 'react-native-gesture-handler';
import { Drawer } from 'expo-router/drawer';

export default function DrawerLayout() {
  return (
    <GestureHandlerRootView style={{ flex: 1 }}>
      <Drawer
        screenOptions={{
          headerShown: true,
          drawerType: 'front',
          swipeEdgeWidth: 50,
        }}
      >
        <Drawer.Screen
          name="(tabs)"
          options={{
            drawerLabel: 'Inicio',
            title: 'Principal',
          }}
        />
        <Drawer.Screen
          name="settings"
          options={{
            drawerLabel: 'Configuración',
            title: 'Ajustes',
          }}
        />
      </Drawer>
    </GestureHandlerRootView>
  );
}

El envoltorio GestureHandlerRootView es un requisito crítico cuando se trabaja con react-native-gesture-handler fuera de Expo Go, especialmente en builds de producción. Su ausencia provoca fallos silenciosos en el reconocimiento de gestos que resultan difíciles de diagnosticar en fases tardías del desarrollo.

Configuración de los Bottom Tabs como Subruta del Drawer

El archivo app/(drawer)/(tabs)/_layout.tsx define la estructura de las pestañas inferiores y su apariencia visual. En este nivel, el desarrollador tiene control total sobre los iconos, etiquetas, colores activos e inactivos, así como sobre la visibilidad del encabezado de cada tab. Una consideración importante es que el header del Drawer generalmente debe deshabilitarse a nivel de los tabs para evitar la superposición de dos barras de título simultáneas.

import { Tabs } from 'expo-router';
import { Ionicons } from '@expo/vector-icons';

export default function TabsLayout() {
  return (
    <Tabs
      screenOptions={{
        headerShown: false, // El Drawer ya provee el header
        tabBarActiveTintColor: '#6200EE',
        tabBarInactiveTintColor: '#9E9E9E',
        tabBarStyle: {
          backgroundColor: '#FFFFFF',
          borderTopWidth: 0,
          elevation: 8,
        },
      }}
    >
      <Tabs.Screen
        name="index"
        options={{
          tabBarLabel: 'Inicio',
          tabBarIcon: ({ color, size }) => (
            <Ionicons name="home-outline" color={color} size={size} />
          ),
        }}
      />
      <Tabs.Screen
        name="explore"
        options={{
          tabBarLabel: 'Explorar',
          tabBarIcon: ({ color, size }) => (
            <Ionicons name="compass-outline" color={color} size={size} />
          ),
        }}
      />
      <Tabs.Screen
        name="profile"
        options={{
          tabBarLabel: 'Perfil',
          tabBarIcon: ({ color, size }) => (
            <Ionicons name="person-outline" color={color} size={size} />
          ),
        }}
      />
    </Tabs>
  );
}

Resolución de Conflictos de Gestos entre el Drawer y los Bottom Tabs

Uno de los problemas más recurrentes al combinar un Drawer con Bottom Tabs en React Native es el conflicto de gestos táctiles. El Drawer detecta deslizamientos horizontales desde el borde izquierdo de la pantalla para abrirse, mientras que ciertas interacciones dentro de los tabs —como listas con scroll horizontal o carruseles— también requieren gestos en la misma dirección. Si este conflicto no se gestiona adecuadamente, la experiencia de usuario se degrada notablemente: el Drawer se abre de manera involuntaria o los componentes internos fallan en registrar el gesto correcto.

La solución principal reside en la correcta configuración del parámetro swipeEdgeWidth del Drawer, que limita la zona sensible de activación del gesto de apertura. Un valor conservador —como 30 a 50 píxeles— minimiza las colisiones con el contenido interior. Adicionalmente, en pantallas que contienen ScrollViews o FlatLists con orientación horizontal, se debe utilizar el componente NativeViewGestureHandler de react-native-gesture-handler para delegar explícitamente la propiedad del gesto al componente correspondiente, evitando que el Drawer intercepte eventos que no le corresponden.

"La gestión correcta del sistema de gestos en aplicaciones React Native no es un detalle cosmético; es una decisión de arquitectura que define la percepción de calidad del producto final por parte del usuario."

Otra estrategia complementaria consiste en deshabilitar el gesto de swipe del Drawer en rutas específicas donde el conflicto sea inevitable, utilizando la propiedad swipeEnabled: false en las opciones de pantalla del Drawer para esa ruta particular. Esto permite un control quirúrgico sobre el comportamiento del navegador según el contexto de cada sección de la aplicación.

Tematización y Consistencia Visual

La integración de una tematización coherente entre el Drawer y los Bottom Tabs es fundamental para construir una interfaz visualmente unificada. Expo Router es compatible con el sistema de temas de React Navigation, lo que permite definir paletas de colores centralizadas que se propagan automáticamente a ambos navegadores. El uso de DarkTheme y DefaultTheme de @react-navigation/native, en conjunto con el hook useColorScheme de React Native, permite implementar soporte para modo oscuro con un mínimo de código adicional.

import { ThemeProvider, DarkTheme, DefaultTheme } from '@react-navigation/native';
import { useColorScheme } from 'react-native';

export default function RootLayout() {
  const colorScheme = useColorScheme();
  return (
    <ThemeProvider value={colorScheme === 'dark' ? DarkTheme : DefaultTheme}>
      {/* Drawer y Tabs heredan automáticamente el tema */}
    </ThemeProvider>
  );
}

La separación clara entre los tokens de diseño —colores, tipografías, espaciados— y la lógica de componentes resulta esencial para mantener la mantenibilidad del proyecto a largo plazo. Se recomienda definir un archivo de constantes de tema centralizado que sea consumido tanto por los layouts de navegación como por los componentes de pantalla, garantizando que cualquier actualización de la identidad visual se propague de manera consistente en toda la aplicación.

Consideraciones de Escalabilidad y Buenas Prácticas

Al escalar una aplicación que combina Drawer y Bottom Tabs, es importante mantener una separación clara de responsabilidades entre los diferentes niveles de navegación. El Drawer debe reservarse para acceder a secciones de configuración global, perfil de usuario, o áreas que no requieren acceso frecuente, mientras que los Bottom Tabs deben alojar las secciones de mayor uso cotidiano de la aplicación. Esta distinción semántica no solo mejora la usabilidad, sino que también facilita las pruebas automatizadas de navegación y la integración de herramientas de deep linking.

Entre las buenas prácticas consolidadas para este patrón de navegación, destacan las siguientes:

  • Mantener el GestureHandlerRootView en el nivel más alto posible del árbol de componentes para garantizar la disponibilidad global del contexto de gestos.
  • Evitar anidar más de dos niveles de navegadores para no degradar el rendimiento de renderizado y la predictibilidad del historial de navegación.
  • Utilizar useFocusEffect en lugar de useEffect para ejecutar lógica que dependa del estado de foco de una pantalla dentro de un stack de tabs.
  • Separar la lógica de autenticación del sistema de navegación mediante layouts de guardia que redireccionen al usuario según su estado de sesión antes de renderizar el Drawer.
  • Documentar la estructura de directorios de rutas en el README del proyecto, dado que la convención de archivos de Expo Router puede no ser intuitiva para desarrolladores que se incorporan al equipo.
  1. Instalar y configurar las dependencias de gestos y animaciones antes de implementar el Drawer.
  2. Definir la estructura de directorios respetando la jerarquía Drawer → Tabs → Pantallas.
  3. Configurar el Drawer con swipeEdgeWidth apropiado para minimizar conflictos de gestos.
  4. Deshabilitar el header duplicado en el layout de tabs cuando el Drawer provea su propio encabezado.
  5. Aplicar el sistema de temas de React Navigation desde el layout raíz para garantizar consistencia visual.

En síntesis, la combinación de Drawer Navigation con Bottom Tabs en Expo Router representa una de las arquitecturas de navegación más completas y versátiles disponibles en el ecosistema React Native. Su correcta implementación requiere atención a los detalles en la configuración del sistema de gestos, la jerarquía de layouts y la coherencia visual, pero el resultado es una aplicación móvil con una experiencia de usuario robusta, escalable y alineada con los estándares de las plataformas iOS y Android.

6
Pylarion Pylarion

Pylarion

Mobile Development Expert

Equipo de Pylarion. Construimos software confiable donde la tecnología no puede fallar.

Blog / Mobile Development / Creación de un Drawer con Bottom Tabs en Expo Router

Comentarios

(0)
Categoría: Mobile Development

Artículos Recomendados

Lanzamiento de SDK 56: expo-widgets alcanza la versión estable
Mobile Development
5
0
0

Lanzamiento de SDK 56: expo-widgets alcanza la versión estable

La reciente actualización a Expo SDK 56 ha marcado un hito importante para los desarrolladores de aplicaciones móviles al promover la biblioteca expo-widgets a su versión estable. Esta importante novedad permite a los programadores construir y diseñar widgets personalizados para la pantalla de inicio, así como Live Activities para la pantalla de bloqueo de los dispositivos, utilizando exclusivamente componentes de React. El aspecto más destacado de esta actualización es que elimina por completo la necesidad de tener conocimientos o escribir código nativo en SwiftUI para lograr la integración con el sistema operativo de Apple. Gracias a esta mejora, los equipos de desarrollo podrán optimizar notablemente sus tiempos de entrega, unificar sus bases de código bajo el ecosistema de React Native y ofrecer experiencias de usuario más dinámicas y nativas en iOS sin salir de su entorno de trabajo habitual, facilitando en gran medida la creación de funcionalidades avanzadas e interactivas.

Leer artículo
Expo Widgets estable en SDK 56
Mobile Development
7
0
0

Expo Widgets estable en SDK 56

La nueva actualización a SDK 56 ha promovido la herramienta expo-widgets a su versión estable, marcando un avance significativo para los desarrolladores. Ahora es posible construir widgets para la pantalla de inicio y Live Activities para la pantalla de bloqueo utilizando exclusivamente componentes de React. Esta innovación elimina por completo la necesidad de programar en SwiftUI o utilizar código nativo de Apple. Como resultado, los equipos de programación pueden mantener su flujo de trabajo basado en React Native para ofrecer experiencias ricas y nativas en iOS. Esta mejora no solo optimiza el tiempo de desarrollo, sino que también reduce la complejidad técnica y la curva de aprendizaje, unificando la creación de interfaces tanto para la aplicación principal como para las extensiones del sistema en una sola base de código eficiente.

Leer artículo
Expo SDK 56: expo-widgets alcanza la versión estable
Mobile Development
1
0
0

Expo SDK 56: expo-widgets alcanza la versión estable

La versión estable de expo-widgets ha sido lanzada oficialmente con la llegada de Expo SDK 56. Esta actualización facilita enormemente el trabajo de los desarrolladores de aplicaciones móviles, permitiendo construir widgets nativos para la pantalla de inicio y Live Activities para la pantalla de bloqueo utilizando únicamente componentes de React. El principal beneficio de esta herramienta es que elimina por completo la necesidad de tener conocimientos previos o escribir código nativo en SwiftUI. De esta forma, se unifica el proceso de creación dentro del ecosistema de React Native, lo que reduce los tiempos de desarrollo, disminuye la barrera de entrada para la implementación de funciones nativas avanzadas en iOS y mejora significativamente la productividad de los equipos enfocados en el ecosistema móvil.

Leer artículo