Implementación de pestañas (Tab Navigator) y navegación en stack

Video
25 min~5 min lectura

Reproductor de video

Concepto clave

En el desarrollo de aplicaciones móviles, la navegación es como el sistema de calles de una ciudad. Imagina que tu app es una ciudad: las pestañas (Tab Navigator) son las avenidas principales que conectan distritos importantes, mientras que la navegación en stack son las calles internas de cada distrito que te permiten explorar en profundidad.

En React Native con Expo, implementamos esta navegación usando React Navigation, la biblioteca estándar de la industria. El Tab Navigator organiza las secciones principales de tu app en pestañas inferiores (iOS) o superiores (Android), mientras que el Stack Navigator maneja las transiciones entre pantallas dentro de cada sección. Esta combinación crea una experiencia de usuario intuitiva que los usuarios de iOS y Android reconocen inmediatamente.

Cómo funciona en la práctica

Vamos a crear una app de noticias con tres secciones principales: Inicio, Búsqueda y Perfil. Cada sección tendrá su propia pestaña, y dentro de cada una, podrás navegar a pantallas detalladas.

Paso 1: Instala las dependencias necesarias. En tu proyecto Expo, ejecuta:

npx expo install @react-navigation/native @react-navigation/bottom-tabs @react-navigation/stack
npx expo install react-native-screens react-native-safe-area-context

Paso 2: Configura la navegación principal. Crearás un Tab Navigator que contenga tres Stack Navigators, uno para cada sección. Esto te permite tener navegación independiente dentro de cada pestaña.

Código en acción

Aquí tienes la implementación completa de nuestra app de noticias:

// App.js
import React from 'react';
import { NavigationContainer } from '@react-navigation/native';
import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
import { createStackNavigator } from '@react-navigation/stack';
import Ionicons from '@expo/vector-icons/Ionicons';

// Pantallas de ejemplo
function HomeScreen() { return null; }
function ArticleScreen() { return null; }
function SearchScreen() { return null; }
function SearchResultsScreen() { return null; }
function ProfileScreen() { return null; }
function SettingsScreen() { return null; }

// Stack Navigators
const HomeStack = createStackNavigator();
function HomeStackScreen() {
  return (
    
      
      
    
  );
}

const SearchStack = createStackNavigator();
function SearchStackScreen() {
  return (
    
      
      
    
  );
}

const ProfileStack = createStackNavigator();
function ProfileStackScreen() {
  return (
    
      
      
    
  );
}

// Tab Navigator principal
const Tab = createBottomTabNavigator();
export default function App() {
  return (
    
       ({
          tabBarIcon: ({ focused, color, size }) => {
            let iconName;
            if (route.name === 'Inicio') {
              iconName = focused ? 'home' : 'home-outline';
            } else if (route.name === 'Buscar') {
              iconName = focused ? 'search' : 'search-outline';
            } else if (route.name === 'Perfil') {
              iconName = focused ? 'person' : 'person-outline';
            }
            return ;
          },
          tabBarActiveTintColor: '#007AFF',
          tabBarInactiveTintColor: 'gray',
        })}
      >
        
        
        
      
    
  );
}

Ahora, veamos cómo navegar entre pantallas dentro de un stack. Aquí está el antes (navegación básica) y después (con parámetros):

// ANTES: Navegación simple
function HomeScreen({ navigation }) {
  return (
     navigation.navigate('Artículo')}
    />
  );
}

// DESPUÉS: Navegación con parámetros
function HomeScreen({ navigation }) {
  const article = { id: 1, title: 'React Native Tips', author: 'Juan Pérez' };
  
  return (
     navigation.navigate('Artículo', { article })}
    />
  );
}

// En ArticleScreen
function ArticleScreen({ route, navigation }) {
  const { article } = route.params;
  return (
    
      {article.title}
      Por: {article.author}
    
  );
}

Errores comunes

  • Anidar Stack Navigators incorrectamente: No coloques un Stack Navigator dentro de otro sin necesidad. Esto crea jerarquías confusas. En su lugar, usa un Tab Navigator con Stack Navigators como hijos.
  • Olvidar headerShown: false: Cuando anidas navigators, aparecen múltiples headers. Configura options={{ headerShown: false }} en las pantallas del Tab Navigator para evitar duplicados.
  • No manejar el estado de navegación: Al pasar entre pestañas, el estado del stack se mantiene. Si necesitas resetearlo, usa navigation.reset() o configura listeners en el Tab Navigator.
  • Iconos inconsistentes entre plataformas: iOS y Android tienen convenciones diferentes para los iconos de pestañas. Usa bibliotecas como @expo/vector-icons y verifica cómo se ven en ambos sistemas.
  • Pasar objetos complejos por parámetros: Evita pasar grandes objetos o funciones por parámetros de navegación. En su lugar, pasa IDs y recupera los datos desde un estado global o una API.

Checklist de dominio

  1. Puedo crear un Tab Navigator con al menos 3 pestañas usando createBottomTabNavigator
  2. Sé configurar iconos personalizados para cada pestaña que cambien según el estado activo/inactivo
  3. Puedo anidar un Stack Navigator dentro de cada pestaña para navegación interna
  4. Sé pasar parámetros entre pantallas y recuperarlos correctamente en la pantalla destino
  5. Puedo manejar el estado de navegación al cambiar entre pestañas (preservar o resetear stacks)
  6. Reconozco y soluciono el problema de headers duplicados en navigators anidados
  7. Sé probar la navegación en ambos dispositivos (iOS y Android) y ajustar para diferencias de plataforma

Crear una app de tienda con navegación por pestañas y stacks

Vas a construir una app de tienda en línea con React Native y Expo que implemente navegación por pestañas y stacks. Sigue estos pasos:

  1. Configuración inicial: Crea un nuevo proyecto Expo con npx create-expo-app TiendaApp e instala las dependencias de React Navigation necesarias.
  2. Estructura de navegación: Implementa un Tab Navigator con 4 pestañas: Inicio, Categorías, Carrito y Perfil. Cada pestaña debe usar Ionicons como iconos.
  3. Stack Navigators: Dentro de cada pestaña, crea un Stack Navigator:
    • Inicio: Pantallas "Productos Destacados" y "Detalle de Producto"
    • Categorías: Pantallas "Lista de Categorías" y "Productos por Categoría"
    • Carrito: Pantallas "Resumen del Carrito" y "Proceso de Pago"
    • Perfil: Pantallas "Mi Perfil" y "Configuración"
  4. Paso de parámetros: En la pantalla "Productos Destacados", crea un botón que navegue a "Detalle de Producto" pasando un objeto producto con id, nombre y precio.
  5. Personalización: Configura colores diferentes para las pestañas activas en iOS (#007AFF) y Android (#6200EE). Usa Platform.OS para detectar el sistema operativo.
  6. Pruebas: Ejecuta la app en un emulador iOS y Android (o dispositivo físico) para verificar que la navegación funcione correctamente en ambas plataformas.
Pistas
  • Recuerda que cada Stack Navigator debe estar envuelto en su propio componente funcional
  • Usa screenOptions en el Tab Navigator para configurar los iconos de manera dinámica basándote en route.name
  • Para los colores por plataforma, puedes crear una función que retorne el color apropiado según Platform.OS

Evalua tu comprension

Completa el quiz interactivo de arriba para ganar XP.