tutoriales.com

Navegación Avanzada en React Native: React Navigation v6

Este tutorial te guiará a través de React Navigation v6, la solución estándar para gestionar la navegación en aplicaciones React Native. Aprenderás a configurar diferentes tipos de navegadores, pasar parámetros entre pantallas y manejar flujos de autenticación para construir una experiencia de usuario robusta y coherente.

Intermedio20 min de lectura4 views16 de marzo de 2026Reportar error

React Native permite a los desarrolladores crear aplicaciones móviles nativas usando JavaScript y React. Una parte fundamental de cualquier aplicación móvil es la navegación, que permite a los usuarios moverse entre diferentes pantallas y secciones de la aplicación. Para esto, la comunidad de React Native ha adoptado React Navigation como la solución estándar y más potente.

En este tutorial, exploraremos React Navigation en su versión 6, la más reciente y mejorada. Cubriremos desde los conceptos básicos hasta técnicas avanzadas para construir flujos de navegación complejos, incluyendo autenticación y anidamiento de navegadores.

🔥 **Importante:** Asegúrate de tener un entorno de desarrollo de React Native configurado (Node.js, npm/yarn, Expo CLI o React Native CLI) antes de comenzar este tutorial.

🚀 ¿Qué es React Navigation?

React Navigation es una librería extensible y personalizable para la navegación en React Native. Proporciona una forma sencilla de construir una jerarquía de pantallas dentro de tu aplicación y manejar las transiciones entre ellas. A diferencia de las soluciones nativas, React Navigation utiliza JavaScript para definir y gestionar la navegación, lo que lo hace muy flexible y fácil de integrar con el estado de tu aplicación.

Ventajas de React Navigation v6 ✨

  • Rendimiento optimizado: Mayor fluidez en las transiciones.
  • API simplificada: Más fácil de usar y comprender.
  • Flexibilidad: Permite anidar diferentes tipos de navegadores.
  • Personalización: Amplias opciones para estilos y comportamientos.
  • Comunidad activa: Gran soporte y documentación.

🛠️ Configuración Inicial

Antes de sumergirnos en la construcción de navegadores, necesitamos instalar React Navigation y sus dependencias.

Paso 1: Crear un proyecto React Native (si no tienes uno)

Si aún no tienes un proyecto, puedes crear uno con Expo CLI (recomendado para empezar) o React Native CLI:

npx create-expo-app MyNavigationApp
cd MyNavigationApp

O si prefieres React Native CLI:

npx react-native init MyNavigationApp --template react-native-template-typescript
cd MyNavigationApp
💡 **Consejo:** Expo Go es una excelente herramienta para probar tus aplicaciones React Native rápidamente en tu dispositivo sin necesidad de compilar el código nativo.

Paso 2: Instalar React Navigation y sus dependencias

Necesitamos instalar el paquete principal @react-navigation/native y sus dependencias de la expo-modules-core (si usas Expo) o react-native-screens y react-native-safe-area-context (para CLI).

Para Expo:

yarn add @react-navigation/native
npx expo install react-native-screens react-native-safe-area-context

Para React Native CLI:

yarn add @react-navigation/native
yarn add react-native-screens react-native-safe-area-context
cd ios && pod install && cd .. # Solo para iOS

Paso 3: Instalar un tipo de navegador (Stack Navigator)

El tipo de navegador más común y el que usaremos para empezar es el Stack Navigator, que proporciona la experiencia de navegación de 'pila' donde las pantallas se empujan una encima de otra.

yarn add @react-navigation/stack

Paso 4: Envolver la aplicación con NavigationContainer

Todas las aplicaciones que usan React Navigation deben estar envueltas en un NavigationContainer. Este componente gestiona el árbol de navegación y contiene el estado de navegación.

Modifica tu App.js (o App.tsx):

// App.js
import 'react-native-gesture-handler'; // Asegúrate de que esta línea esté al inicio si usas React Native CLI
import * as React from 'react';
import { NavigationContainer } from '@react-navigation/native';
import { createStackNavigator } from '@react-navigation/stack';
import { View, Text, Button } from 'react-native';

// Componentes de pantalla de ejemplo
function HomeScreen({ navigation }) {
  return (
    <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
      <Text>¡Bienvenido a Casa!</Text>
      <Button
        title="Ir a Detalles"
        onPress={() => navigation.navigate('Details')}
      />
    </View>
  );
}

function DetailsScreen({ navigation }) {
  return (
    <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
      <Text>Pantalla de Detalles</Text>
      <Button
        title="Volver a Casa"
        onPress={() => navigation.goBack()}
      />
    </View>
  );
}

const Stack = createStackNavigator();

function App() {
  return (
    <NavigationContainer>
      <Stack.Navigator initialRouteName="Home">
        <Stack.Screen name="Home" component={HomeScreen} options={{ title: 'Mi Inicio' }} />
        <Stack.Screen name="Details" component={DetailsScreen} options={{ title: 'Más Detalles' }} />
      </Stack.Navigator>
    </NavigationContainer>
  );
}

export default App;
📌 **Nota:** Si usas React Native CLI, es crucial añadir `import 'react-native-gesture-handler';` al principio de tu `App.js` para que los gestos de deslizamiento funcionen correctamente. Para Expo, esto generalmente no es necesario.

📂 Tipos de Navegadores Comunes

React Navigation ofrece varios tipos de navegadores para diferentes patrones de interfaz de usuario. Los más comunes son:

1. Stack Navigator (Pila) 📚

El Stack Navigator es ideal para navegar entre pantallas de forma secuencial, como si estuvieras apilando cartas. Cada vez que navegas a una nueva pantalla, se empuja en la pila, y al retroceder, se saca la pantalla superior.

Uso:

import { createStackNavigator } from '@react-navigation/stack';

const Stack = createStackNavigator();

function MyStack() {
  return (
    <Stack.Navigator>
      <Stack.Screen name="First" component={FirstScreen} />
      <Stack.Screen name="Second" component={SecondScreen} />
    </Stack.Navigator>
  );
}

Opciones Comunes para Stack Navigator

Puedes personalizar el Stack Navigator y sus pantallas con el prop options en Stack.Screen o screenOptions en Stack.Navigator.

OpciónDescripciónEjemplo
titleTítulo de la cabecera de la pantalla.'Mi Pantalla'
headerStyleEstilos para el contenedor de la cabecera.{ backgroundColor: '#f4511e' }
headerTintColorColor del texto y los iconos de la cabecera.'#fff'
headerTitleStyleEstilos para el texto del título.{ fontWeight: 'bold' }
headerBackTitleTítulo del botón de retroceso en iOS.'Atrás'
gestureEnabledHabilita/deshabilita el gesto de deslizamiento para retroceder.false

2. Tab Navigator (Pestañas) 📑

El Tab Navigator (comúnmente Bottom Tab Navigator) es perfecto para la navegación de nivel superior, donde el usuario puede cambiar entre secciones principales de la aplicación con un solo toque. Las pestañas suelen estar en la parte inferior de la pantalla.

Instalación:

yarn add @react-navigation/bottom-tabs

Uso:

import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
import Ionicons from 'react-native-vector-icons/Ionicons'; // Ejemplo para iconos

// Pantallas de ejemplo
function FeedScreen() { /* ... */ }
function SettingsScreen() { /* ... */ }

const Tab = createBottomTabNavigator();

function MyTabs() {
  return (
    <Tab.Navigator
      screenOptions={({ route }) => ({
        tabBarIcon: ({ focused, color, size }) => {
          let iconName;
          if (route.name === 'Feed') {
            iconName = focused ? 'ios-information-circle' : 'ios-information-circle-outline';
          } else if (route.name === 'Settings') {
            iconName = focused ? 'ios-list-box' : 'ios-list';
          }
          return <Ionicons name={iconName} size={size} color={color} />;
        },
        tabBarActiveTintColor: 'tomato',
        tabBarInactiveTintColor: 'gray',
      })}
    >
      <Tab.Screen name="Feed" component={FeedScreen} options={{ title: 'Noticias' }} />
      <Tab.Screen name="Settings" component={SettingsScreen} options={{ title: 'Ajustes' }} />
    </Tab.Navigator>
  );
}
⚠️ **Advertencia:** Para usar `react-native-vector-icons` asegúrate de haberlo instalado y configurado correctamente en tu proyecto. Si usas Expo, `expo install react-native-vector-icons` y estará listo. Para React Native CLI, sigue las instrucciones de instalación nativas.

3. Drawer Navigator (Lateral) ☰

El Drawer Navigator (cajón lateral) es útil para aplicaciones con muchas secciones o para navegación secundaria. Se abre deslizando desde el borde de la pantalla o tocando un icono de menú.

Instalación:

yarn add @react-navigation/drawer

Uso:

import { createDrawerNavigator } from '@react-navigation/drawer';

// Pantallas de ejemplo
function ArticleScreen() { /* ... */ }
function ProfileScreen() { /* ... */ }

const Drawer = createDrawerNavigator();

function MyDrawer() {
  return (
    <Drawer.Navigator initialRouteName="Articles">
      <Drawer.Screen name="Articles" component={ArticleScreen} />
      <Drawer.Screen name="Profile" component={ProfileScreen} />
    </Drawer.Navigator>
  );
}

🧩 Anidando Navegadores

Uno de los puntos fuertes de React Navigation es la capacidad de anidar navegadores. Esto significa que puedes tener, por ejemplo, un Stack Navigator dentro de una de las pestañas de un Tab Navigator. Esto es crucial para construir interfaces complejas y coherentes.

Ejemplo: Un Tab Navigator con Stack Navigators en cada pestaña.

Imagina que tienes una aplicación con pestañas de 'Inicio' y 'Perfil'. Dentro de 'Inicio', quieres tener una pila de navegación (Inicio -> Detalles del producto). Dentro de 'Perfil', también quieres una pila (Perfil -> Editar perfil).

// Stack para la pestaña de Inicio
const HomeStack = createStackNavigator();

function HomeStackScreen() {
  return (
    <HomeStack.Navigator>
      <HomeStack.Screen name="Home" component={HomeScreen} options={{ title: 'Inicio App' }} />
      <HomeStack.Screen name="ProductDetails" component={ProductDetailsScreen} options={{ title: 'Detalles' }} />
    </HomeStack.Navigator>
  );
}

// Stack para la pestaña de Perfil
const ProfileStack = createStackNavigator();

function ProfileStackScreen() {
  return (
    <ProfileStack.Navigator>
      <ProfileStack.Screen name="Profile" component={ProfileScreen} options={{ title: 'Mi Perfil' }} />
      <ProfileStack.Screen name="EditProfile" component={EditProfileScreen} options={{ title: 'Editar' }} />
    </ProfileStack.Navigator>
  );
}

// El Tab Navigator principal
const Tab = createBottomTabNavigator();

function AppTabs() {
  return (
    <Tab.Navigator>
      <Tab.Screen name="HomeTab" component={HomeStackScreen} options={{ headerShown: false, title: 'Inicio' }} />
      <Tab.Screen name="ProfileTab" component={ProfileStackScreen} options={{ headerShown: false, title: 'Perfil' }} />
    </Tab.Navigator>
  );
}

// Y finalmente, el NavigationContainer principal
function App() {
  return (
    <NavigationContainer>
      <AppTabs />
    </NavigationContainer>
  );
}

export default App;
🔥 **Importante:** Observa `options={{ headerShown: false }}` en los `Tab.Screen`. Esto evita que aparezca una doble cabecera (una del Tab y otra del Stack anidado). Es crucial cuando anidas navegadores.
NavigationContainer Tab Navigator (2 Pestañas) Stack Navigator (Inicio) Home ProductDetails Stack Navigator (Perfil) Profile EditProfile

🔗 Pasando Parámetros Entre Pantallas

Es muy común necesitar pasar datos de una pantalla a otra. React Navigation facilita esto a través del objeto params.

Envío de parámetros

Cuando navegas a una pantalla, puedes pasar un segundo argumento con un objeto de parámetros:

function HomeScreen({ navigation }) {
  return (
    <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
      <Text>Inicio</Text>
      <Button
        title="Ir a Detalles de Usuario (ID: 123)"
        onPress={() => navigation.navigate('UserDetails', { userId: 123, userName: 'Alice' })}
      />
    </View>
  );
}

Recepción de parámetros

En la pantalla de destino, los parámetros están disponibles a través de route.params en el objeto route que se pasa como prop a los componentes de la pantalla:

function UserDetailsScreen({ route, navigation }) {
  const { userId, userName } = route.params;

  return (
    <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
      <Text>Detalles del Usuario</Text>
      <Text>ID: {userId}</Text>
      <Text>Nombre: {userName}</Text>
      <Button title="Volver" onPress={() => navigation.goBack()} />
    </View>
  );
}

// Asegúrate de añadir esta pantalla al Stack Navigator
// <Stack.Screen name="UserDetails" component={UserDetailsScreen} />
💡 **Consejo:** Para una tipificación fuerte en TypeScript, puedes definir los tipos de parámetros para cada ruta. Esto mejora la seguridad y la experiencia de desarrollo.

🔐 Flujo de Autenticación

Un patrón muy común en aplicaciones móviles es un flujo de autenticación, donde los usuarios navegan entre pantallas de Login, Registro, Recuperar Contraseña antes de acceder a la parte principal de la aplicación. Una vez autenticados, se les muestra la interfaz de usuario de la aplicación. React Navigation maneja esto elegantemente con navegadores anidados condicionalmente.

El enfoque es tener un Stack Navigator principal que muestre:

  1. Un Stack Navigator de autenticación (Login, Registro, etc.) si el usuario no está autenticado.
  2. Un Tab Navigator (o Drawer Navigator) de la aplicación principal si el usuario está autenticado.

Estructura de código para autenticación

Primero, definamos las pantallas de autenticación y la aplicación principal.

// AuthStack.js
import React from 'react';
import { createStackNavigator } from '@react-navigation/stack';
import { View, Text, Button } from 'react-native';

const AuthStack = createStackNavigator();

function SignInScreen({ navigation, signIn }) {
  return (
    <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
      <Text>Pantalla de Inicio de Sesión</Text>
      <Button title="Iniciar Sesión" onPress={() => signIn()} />
      <Button title="Registrarse" onPress={() => navigation.navigate('SignUp')} />
    </View>
  );
}

function SignUpScreen({ navigation }) {
  return (
    <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
      <Text>Pantalla de Registro</Text>
      <Button title="Volver a Iniciar Sesión" onPress={() => navigation.goBack()} />
    </View>
  );
}

export function AuthStackNavigator({ signIn }) {
  return (
    <AuthStack.Navigator>
      <AuthStack.Screen name="SignIn">
        {props => <SignInScreen {...props} signIn={signIn} />}
      </AuthStack.Screen>
      <AuthStack.Screen name="SignUp" component={SignUpScreen} />
    </AuthStack.Navigator>
  );
}

// AppStack.js (Navegador principal de la aplicación autenticada)
import React from 'react';
import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
import { createStackNavigator } from '@react-navigation/stack';
import { View, Text, Button } from 'react-native';
import Ionicons from 'react-native-vector-icons/Ionicons';

// Pantallas de ejemplo para la aplicación principal
function DashboardScreen({ signOut }) {
  return (
    <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
      <Text>Panel de Control</Text>
      <Button title="Cerrar Sesión" onPress={() => signOut()} />
    </View>
  );
}

function SettingsAppScreen() {
  return (
    <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
      <Text>Ajustes de la App</Text>
    </View>
  );
}

const Tab = createBottomTabNavigator();

export function AppTabNavigator({ signOut }) {
  return (
    <Tab.Navigator
      screenOptions={({ route }) => ({
        tabBarIcon: ({ focused, color, size }) => {
          let iconName;
          if (route.name === 'Dashboard') {
            iconName = focused ? 'ios-speedometer' : 'ios-speedometer-outline';
          } else if (route.name === 'Settings') {
            iconName = focused ? 'ios-settings' : 'ios-settings-outline';
          }
          return <Ionicons name={iconName} size={size} color={color} />;
        },
        tabBarActiveTintColor: 'blue',
        tabBarInactiveTintColor: 'gray',
        headerShown: false // Oculta la cabecera del Tab Navigator si ya hay una externa o si no quieres una
      })}
    >
      <Tab.Screen name="Dashboard">
        {props => <DashboardScreen {...props} signOut={signOut} />}
      </Tab.Screen>
      <Tab.Screen name="Settings" component={SettingsAppScreen} />
    </Tab.Navigator>
  );
}

// App.js (Contenedor principal con lógica de autenticación)
import * as React from 'react';
import { NavigationContainer } from '@react-navigation/native';
import { AuthStackNavigator } from './AuthStack'; // Asume que creaste estos archivos
import { AppTabNavigator } from './AppStack';
import { ActivityIndicator, View, AsyncStorage } from 'react-native'; // Usar SecureStore en producción

const AuthContext = React.createContext();

function App() {
  const [state, dispatch] = React.useReducer(
    (prevState, action) => {
      switch (action.type) {
        case 'RESTORE_TOKEN':
          return {
            ...prevState,
            userToken: action.token,
            isLoading: false,
          };
        case 'SIGN_IN':
          return {
            ...prevState,
            isSignout: false,
            userToken: action.token,
          };
        case 'SIGN_OUT':
          return {
            ...prevState,
            isSignout: true,
            userToken: null,
          };
      }
    },
    {
      isLoading: true,
      isSignout: false,
      userToken: null,
    }
  );

  React.useEffect(() => {
    // Recuperar el token del almacenamiento al iniciar la app
    const bootstrapAsync = async () => {
      let userToken;
      try {
        // En una app real, usarías SecureStore para tokens sensibles
        userToken = await AsyncStorage.getItem('userToken'); 
      } catch (e) {
        // Restaurar token falló
      }
      dispatch({ type: 'RESTORE_TOKEN', token: userToken });
    };
    bootstrapAsync();
  }, []);

  const authContext = React.useMemo(
    () => ({
      signIn: async (data) => {
        // Aquí deberías realizar una llamada a la API para autenticar
        // Por simplicidad, simulamos un token
        const userToken = 'dummy-auth-token';
        await AsyncStorage.setItem('userToken', userToken);
        dispatch({ type: 'SIGN_IN', token: userToken });
      },
      signOut: async () => {
        await AsyncStorage.removeItem('userToken');
        dispatch({ type: 'SIGN_OUT' });
      },
      signUp: async (data) => {
        // Aquí harías una llamada a la API para registrar al usuario
        // Y luego lo iniciarías sesión
        const userToken = 'dummy-auth-token-new-user';
        await AsyncStorage.setItem('userToken', userToken);
        dispatch({ type: 'SIGN_IN', token: userToken });
      },
    }),
    []
  );

  if (state.isLoading) {
    return (
      <View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
        <ActivityIndicator size="large" />
      </View>
    );
  }

  return (
    <AuthContext.Provider value={authContext}>
      <NavigationContainer>
        {state.userToken == null ? (
          <AuthStackNavigator signIn={authContext.signIn} />
        ) : (
          <AppTabNavigator signOut={authContext.signOut} />
        )}
      </NavigationContainer>
    </AuthContext.Provider>
  );
}

export default App;
📌 **Nota:** Para el almacenamiento de tokens sensibles, es **altamente recomendado** usar `expo-secure-store` (para Expo) o `react-native-keychain` (para React Native CLI) en lugar de `AsyncStorage`. `AsyncStorage` no es seguro para datos sensibles.

En este patrón, el NavigationContainer decide qué conjunto de navegadores renderizar basándose en el estado de autenticación (userToken). Cuando userToken es null, se muestra el AuthStackNavigator. Cuando hay un userToken, se muestra el AppTabNavigator.

App.js ¿userToken == null? Auth Stack Navigator App Tab Navigator SignIn SignUp Dashboard Settings No Éxito Cerrar Sesión

🎨 Personalización de Navegadores

React Navigation es altamente personalizable. Puedes ajustar casi todos los aspectos de la apariencia y el comportamiento.

Opciones de cabecera (Stack Navigator)

Las cabeceras son una parte clave de la interfaz. Puedes personalizar su estilo, los botones, los títulos y más.

<Stack.Screen
  name="HomeScreen"
  component={HomeScreen}
  options={{
    title: 'Mi Gran App',
    headerStyle: {
      backgroundColor: '#6200EE', // Color de fondo
    },
    headerTintColor: '#fff', // Color del texto y los iconos
    headerTitleStyle: {
      fontWeight: 'bold',
    },
    headerRight: () => (
      <Button
        onPress={() => alert('¡Presionaste el botón!')}
        title="Info"
        color="#fff"
      />
    ),
    headerLeft: () => (
      <Button
        onPress={() => alert('¡Menú!')}
        title="Menú"
        color="#fff"
      />
    )
  }}
/>

Custom Drawer Content

Para el Drawer Navigator, puedes ir más allá de la lista de enlaces por defecto y crear tu propio componente para el contenido del cajón.

import {
  DrawerContentScrollView,
  DrawerItemList,
  DrawerItem,
} from '@react-navigation/drawer';
import { Text, View, StyleSheet, Image } from 'react-native';

function CustomDrawerContent(props) {
  return (
    <DrawerContentScrollView {...props}>
      <View style={styles.drawerHeader}>
        <Image
          source={{ uri: 'https://reactnative.dev/img/tiny_logo.png' }}
          style={styles.drawerImage}
        />
        <Text style={styles.drawerHeaderText}>Mi Perfil de Usuario</Text>
      </View>
      <DrawerItemList {...props} />
      <DrawerItem
        label="Ayuda"
        onPress={() => alert('¡Necesitas ayuda!')}
        icon={({ color, size }) => (
          <Ionicons name="help-circle-outline" size={size} color={color} />
        )}
      />
    </DrawerContentScrollView>
  );
}

// Luego, en tu Drawer Navigator:
// <Drawer.Navigator drawerContent={props => <CustomDrawerContent {...props} />}>
const styles = StyleSheet.create({
  drawerHeader: {
    padding: 20,
    backgroundColor: '#f0f0f0',
    alignItems: 'center',
    justifyContent: 'center',
  },
  drawerImage: {
    width: 80,
    height: 80,
    borderRadius: 40,
    marginBottom: 10,
  },
  drawerHeaderText: {
    fontSize: 18,
    fontWeight: 'bold',
  },
});

⏭️ Consideraciones Avanzadas

Deep Linking

React Navigation tiene un soporte robusto para Deep Linking, permitiendo que los usuarios abran tu aplicación directamente en una pantalla específica a través de un enlace web o un enlace universal. Esto es crucial para la experiencia de usuario y el marketing.

La configuración implica definir un linking prop en tu NavigationContainer.

const linking = {
  prefixes: ['mychatapp://', 'https://mychatapp.com'],
  config: {
    screens: {
      HomeTab: {
        screens: {
          Feed: 'feed',
          ProductDetails: 'product/:id',
        },
      },
      ProfileTab: 'profile',
    },
  },
};

function App() {
  return (
    <NavigationContainer linking={linking} fallback={<Text>Cargando...</Text>}>
      {/* ... tus navegadores ... */}
    </NavigationContainer>
  );
}
🔥 **Importante:** La configuración de Deep Linking también requiere configuración nativa específica para iOS (URL Schemes y Universal Links) y Android (Intent Filters y App Links). Consulta la documentación oficial de React Navigation para los detalles específicos de cada plataforma.

Tematización (Theming)

Puedes aplicar temas globales a tu aplicación para asegurarte de que los colores y estilos de navegación coincidan con el resto de tu interfaz.

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

const MyTheme = {
  ...DefaultTheme,
  colors: {
    ...DefaultTheme.colors,
    primary: 'rgb(255, 45, 85)',
    background: 'rgb(242, 242, 242)',
    card: 'rgb(255, 255, 255)',
    text: 'rgb(28, 28, 30)',
    border: 'rgb(199, 199, 204)',
    notification: 'rgb(255, 69, 58)',
  },
};

function App() {
  const scheme = useColorScheme(); // 'light' o 'dark'

  return (
    <NavigationContainer theme={scheme === 'dark' ? DarkTheme : MyTheme}>
      {/* ... */}
    </NavigationContainer>
  );
}

✅ Buenas Prácticas y Consejos

  • Organiza tu código: Separa los navegadores en archivos (AuthStack.js, AppTabs.js, etc.) para mantener la claridad.
  • Usa useNavigation y useRoute hooks: En lugar de pasar navigation y route como props, puedes usar estos hooks dentro de tus componentes para acceder a ellos.
import { useNavigation, useRoute } from '@react-navigation/native';
// ...
const navigation = useNavigation();
const route = useRoute();
const { userId } = route.params;
  • Evita pasar props excesivamente: Si una pantalla necesita muchos datos, considera usar un sistema de gestión de estado global (Redux, Context API, Zustand, etc.).
  • Optimiza el rendimiento: Ten en cuenta que cada pantalla es un componente de React. Evita renderizados innecesarios.
  • Prueba a fondo: Asegúrate de que todos los flujos de navegación funcionen como se espera, especialmente los de autenticación y los casos extremos.
💡 **Consejo:** Para una tipificación robusta con TypeScript, define una interfaz `RootStackParamList` para tus rutas y parámetros. Esto te dará autocompletado y detección de errores en tiempo de compilación.
Ejemplo de tipificación con TypeScript
// types.ts
export type RootStackParamList = {
  Home: undefined; // No toma parámetros
  Details: { itemId: number; otherParam?: string }; // itemId es requerido, otherParam es opcional
  UserDetails: { userId: number; userName: string };
  SignIn: undefined;
  SignUp: undefined;
  Dashboard: undefined;
  Settings: undefined;
  // Para anidar stacks, define los sub-stacks aquí también
  HomeStack: undefined;
  ProfileStack: undefined;
  Feed: undefined;
  ProductDetails: { id: string };
  Profile: undefined;
  EditProfile: undefined;
};

// Y en tus componentes:
import { StackScreenProps } from '@react-navigation/stack';
import { CompositeScreenProps } from '@react-navigation/native';
import { BottomTabScreenProps } from '@react-navigation/bottom-tabs';

type HomeScreenProps = StackScreenProps<RootStackParamList, 'Home'>;

function HomeScreen({ navigation }: HomeScreenProps) { /* ... */ }

// Para una pantalla en un tab que está dentro de un stack:
type ProductDetailsScreenProps = CompositeScreenProps<
  StackScreenProps<RootStackParamList, 'ProductDetails'>,
  BottomTabScreenProps<RootStackParamList, 'HomeStack'> // Aquí HomeStack no toma parámetros, pero lo enlaza
>;

function ProductDetailsScreen({ route }: ProductDetailsScreenProps) {
  const { id } = route.params;
  // ...
}

Conclusión

Dominar React Navigation es un pilar fundamental para construir aplicaciones React Native de alta calidad. Hemos cubierto la configuración inicial, los tipos de navegadores más comunes (Stack, Tab, Drawer), cómo anidarlos para crear arquitecturas complejas, el manejo de parámetros y la implementación de un flujo de autenticación robusto. Con estas herramientas, estás bien equipado para diseñar y desarrollar experiencias de usuario fluidas y profesionales en tus proyectos móviles.

Sigue experimentando con las opciones de personalización y explora la documentación oficial para descubrir aún más posibilidades. ¡Feliz navegación!

Comentarios (0)

Aún no hay comentarios. ¡Sé el primero!