Implementación de Navegación con React Navigation

Lectura
20 min~10 min lectura
Objetivo de la lección

React Navigation es la biblioteca estándar de facto para manejar esta navegación en aplicaciones construidas con React Native.

Puntos de control
  • Introducción a React Navigation: El Sistema de Carreteras de tu App
  • Concepto Clave: Navegadores, Rutas y Parámetros
  • Cómo Funciona en la Práctica: Configuración de un Stack Navigator
  • Código en Acción: Navegación y Paso de Parámetros

Introducción a React Navigation: El Sistema de Carreteras de tu App

En el desarrollo de aplicaciones móviles, la capacidad de moverse entre diferentes pantallas es tan fundamental como la existencia de calles en una ciudad. React Navigation es la biblioteca estándar de facto para manejar esta navegación en aplicaciones construidas con React Native. Su propósito es proporcionar una infraestructura robusta, performante y con una experiencia de usuario nativa para gestionar la pila de pantallas, los tabs, los drawers y otros patrones de navegación complejos. Sin una solución de navegación, tu aplicación sería una única pantalla estática, severamente limitada en funcionalidad y utilidad.

Esta lección se enfoca en la implementación práctica de React Navigation, asumiendo que ya tienes un proyecto de Expo o React Native configurado. Exploraremos los conceptos centrales, configuraremos un navegador de pila (Stack Navigator), pasaremos parámetros entre pantallas y manejaremos la navegación de manera programática. A diferencia de la navegación web basada en URLs, la navegación móvil se gestiona a través de una pila de rutas, donde cada pantalla se "apila" sobre la anterior, y React Navigation abstrae esta complejidad en una API declarativa y fácil de usar.

Es crucial entender que React Navigation es una biblioteca puramente de JavaScript que recrea los gestos y transiciones nativos. Esto le otorga una gran flexibilidad y permite un desarrollo consistente entre iOS y Android, aunque siempre con la posibilidad de personalizar el comportamiento para cada plataforma. Su integración con el ecosistema de Expo es perfecta, ya que funciona sin necesidad de configurar enlaces nativos (native linking), lo que acelera enormemente el proceso de desarrollo.

Concepto Clave: Navegadores, Rutas y Parámetros

Para dominar React Navigation, debes internalizar tres conceptos fundamentales: los Navegadores, las Rutas y los Parámetros. Imagina que estás construyendo un centro comercial. El Navegador (por ejemplo, un Stack Navigator) es la estructura física del edificio que define cómo se conectan las tiendas (pantallas). Un Navigator es un componente que define cómo se presentan y transicionan las pantallas de tu aplicación. Existen varios tipos: Stack (pila), Tab (pestañas), Drawer (cajón), entre otros.

La Ruta (o Screen) es cada tienda individual dentro del centro comercial, como la zapatería o la librería. Cada pantalla de tu aplicación es una ruta con un nombre único. Finalmente, los Parámetros son la mercancía específica que le quieres mostrar a un cliente cuando entra a una tienda. Por ejemplo, al navegar a la pantalla de "Detalles de Producto", le pasas como parámetro el `id` del producto que debe mostrar. Esta separación de responsabilidades (estructura, destino y datos) es la clave para una navegación limpia y mantenible.

La navegación funciona mediante un objeto de navigación y un objeto de ruta que se pasan como props a cada pantalla que está definida dentro de un navegador. El objeto de navegación contiene métodos como `navigate()`, `goBack()`, y `push()` que te permiten cambiar de pantalla. El objeto de ruta contiene información sobre la ruta actual, incluyendo su nombre y los parámetros que recibió. Comprender esta dualidad es esencial para controlar el flujo de tu aplicación.

Tip del Instructor: No confundas React Navigation con la navegación nativa (por ejemplo, usando `react-native-navigation`). React Navigation es una implementación en JavaScript que es más fácil de configurar y más flexible para la mayoría de los casos de uso, especialmente en Expo. Es la elección recomendada para comenzar y para un amplio rango de aplicaciones en producción.

Cómo Funciona en la Práctica: Configuración de un Stack Navigator

La implementación práctica comienza con la instalación de los paquetes necesarios. En un proyecto de Expo, puedes hacerlo con un solo comando que instala las bibliotecas core y las dependencias para un Stack Navigator, que es el tipo más común. Este comando asegura la compatibilidad y evita conflictos de versiones. Una vez instalado, el patrón de implementación sigue una estructura clara: crear un navegador, definir las pantallas dentro de él y luego renderizar ese navegador como el componente principal de tu aplicación (o de una sección de ella).

El siguiente paso es envolver tu aplicación (o la sección donde necesitas navegación) en un componente NavigationContainer. Este componente es el proveedor de contexto que gestiona el estado de navegación de toda tu app y debe renderizarse en la raíz. Dentro de él, defines tu navegador. Para un Stack Navigator, utilizas la función `createStackNavigator` (o `createNativeStackNavigator` para un rendimiento y apariencia más nativa), la cual retorna dos componentes: el `` que define la configuración global de la pila, y el `` que define cada pantalla individual.

Veamos un ejemplo paso a paso de configuración inicial. Primero, importamos los componentes necesarios. Luego, creamos una instancia del Stack Navigator. Después, definimos nuestro componente de navegación, que contiene el `NavigationContainer` y dentro el `Stack.Navigator` con sus `Stack.Screen`. Finalmente, exportamos este componente de navegación para usarlo en nuestro punto de entrada (por ejemplo, `App.js`). Cada `Stack.Screen` tiene un prop `name` (el nombre de la ruta) y un prop `component` (el componente de React que renderiza la pantalla).

// 1. Importaciones
import * as React from 'react';
import { NavigationContainer } from '@react-navigation/native';
import { createNativeStackNavigator } from '@react-navigation/native-stack';
import PantallaInicio from './PantallaInicio';
import PantallaDetalles from './PantallaDetalles';

// 2. Crear una instancia del Stack Navigator
const Stack = createNativeStackNavigator();

// 3. Definir el componente principal de navegación
function NavegacionApp() {
  return (
    <NavigationContainer>
      <Stack.Navigator initialRouteName="Inicio">
        <Stack.Screen
          name="Inicio"
          component={PantallaInicio}
          options={{ title: 'Bienvenido' }}
        />
        <Stack.Screen
          name="Detalles"
          component={PantallaDetalles}
          options={{ title: 'Detalles del Item' }}
        />
      </Stack.Navigator>
    </NavigationContainer>
  );
}

// 4. Exportar
export default NavegacionApp;

Código en Acción: Navegación y Paso de Parámetros

Con el navegador configurado, el siguiente paso es realizar la navegación entre pantallas y pasar datos entre ellas. Esto se hace utilizando el objeto `navigation` que se recibe como prop en cada pantalla. Para navegar a otra pantalla, se llama a `navigation.navigate('NombreDeLaRuta')`. Si necesitas pasar datos, agregas un segundo argumento a esta función: un objeto que contendrá los parámetros. Estos parámetros serán accesibles en la pantalla destino a través de `route.params`.

Vamos a crear un ejemplo completo y funcional. Tendremos una pantalla de inicio (`PantallaInicio`) que muestra una lista de elementos. Al presionar un elemento, navegaremos a una pantalla de detalles (`PantallaDetalles`) y le pasaremos el ID y el nombre del elemento seleccionado. La pantalla de detalles mostrará esta información. También implementaremos un botón para regresar a la pantalla anterior usando `navigation.goBack()` y otro para ir al inicio usando `navigation.popToTop()`.

Es importante manejar el caso en el que `route.params` pueda ser `undefined`. Una práctica común es usar desestructuración con valores por defecto. Además, para una mejor experiencia de desarrollo, TypeScript es altamente recomendado con React Navigation para tener tipado seguro en los nombres de ruta y los parámetros, pero en este ejemplo nos mantendremos en JavaScript puro por simplicidad.

// PantallaInicio.js
import React from 'react';
import { View, Button, Text, FlatList, TouchableOpacity, StyleSheet } from 'react-native';

function PantallaInicio({ navigation }) {
  // Datos de ejemplo
  const elementos = [
    { id: '1', nombre: 'React Native' },
    { id: '2', nombre: 'Expo' },
    { id: '3', nombre: 'React Navigation' },
  ];

  const renderItem = ({ item }) => (
    <TouchableOpacity
      style={styles.item}
      => {
        // Navegar a Detalles y pasar parámetros
        navigation.navigate('Detalles', {
          itemId: item.id,
          itemNombre: item.nombre,
        });
      }}
    >
      <Text style={styles.texto}>{item.nombre}</Text>
    </TouchableOpacity>
  );

  return (
    <View style={styles.contenedor}>
      <Text style={styles.titulo}>Lista de Elementos</Text>
      <FlatList
        data={elementos}
        renderItem={renderItem}
        keyExtractor={item => item.id}
      />
      <Button
        title="Ir a Detalles (sin parámetros)"
        => navigation.navigate('Detalles')}
      />
    </View>
  );
}

const styles = StyleSheet.create({
  contenedor: { flex: 1, padding: 20 },
  titulo: { fontSize: 24, marginBottom: 20 },
  item: { padding: 15, backgroundColor: '#f0f0f0', marginBottom: 10, borderRadius: 5 },
  texto: { fontSize: 18 },
});

export default PantallaInicio;
// PantallaDetalles.js
import React from 'react';
import { View, Text, Button, StyleSheet } from 'react-native';

function PantallaDetalles({ route, navigation }) {
  // Desestructurar parámetros con valores por defecto para evitar errores
  const { itemId, itemNombre } = route.params || {};

  return (
    <View style={styles.contenedor}>
      <Text style={styles.titulo}>Pantalla de Detalles</Text>
      {itemId ? (
        <>
          <Text style={styles.texto}>ID recibido: {itemId}</Text>
          <Text style={styles.texto}>Nombre recibido: {itemNombre}</Text>
        </>
      ) : (
        <Text style={styles.texto}>No se recibieron parámetros.</Text>
      )}
      <Button title="Volver Atrás" => navigation.goBack()} />
      <Button title="Ir al Inicio" => navigation.popToTop()} />
      <Button
        title="Actualizar Parámetros"
        =>
          // También se pueden actualizar los parámetros de la ruta actual
          navigation.setParams({ itemId: '99', itemNombre: 'Actualizado!' })
        }
      />
    </View>
  );
}

const styles = StyleSheet.create({
  contenedor: { flex: 1, padding: 20, justifyContent: 'center' },
  titulo: { fontSize: 28, marginBottom: 30, textAlign: 'center' },
  texto: { fontSize: 20, marginBottom: 15 },
});

export default PantallaDetalles;

Errores Comunes y Cómo Evitarlos

Al implementar React Navigation, es frecuente tropezar con los mismos obstáculos. Identificarlos de antemano te ahorrará horas de depuración.

1. Olvidar el NavigationContainer: Este es el error más común para principiantes. El componente `NavigationContainer` debe envolver a todos tus navegadores en el nivel más alto de tu aplicación. Sin él, los hooks de navegación (como `useNavigation`) no funcionarán y no podrás navegar. Solución: Asegúrate siempre de que tu `App.js` (o componente raíz) renderice el `<NavigationContainer>`.

2. Pasar parámetros incorrectamente o no manejarlos como undefined: Intentar acceder a `route.params.itemId` sin verificar si `route.params` existe causará un error. Solución: Usa desestructuración con valores por defecto (`const { itemId } = route.params || {};`) o verifica condicionalmente (`route.params?.itemId`).

3. Confusión entre `navigate` y `push`: `navigation.navigate('Ruta')` irá a la pantalla si ya existe en la pila, mientras que `navigation.push('Ruta')` siempre agregará una nueva instancia, incluso si es la misma pantalla. Usar `navigate` cuando quieres `push` puede llevar a un comportamiento inesperado en la pila. Solución: Usa `navigate` para ir a pantallas distintas y `push` cuando necesites múltiples instancias de la misma pantalla (por ejemplo, en un flujo de profundidad).

4. No configurar correctamente las opciones de pantalla (headers): Los headers pueden no aparecer o superponerse si no se configuran las `options` correctamente en el `Stack.Screen` o mediante `navigation.setOptions`. Solución: Configura los títulos y estilos en las `options` del `Stack.Screen`. Para cambios dinámicos (como un título que depende de parámetros), usa `navigation.setOptions` dentro de un `useLayoutEffect` en el componente de la pantalla.

5. Problemas de rendimiento con re-renders innecesarios: Pasar funciones en línea (inline functions) o objetos nuevos como parámetros o props de opciones puede causar re-renders no deseados. Solución: Usa `React.useCallback` para memoizar funciones y `React.useMemo` para objetos complejos que se pasan como parámetros o en `options`.

Tip de Depuración: Si la navegación no funciona, verifica este orden: 1) ¿Está el `NavigationContainer` presente? 2) ¿El `name` de la ruta en `navigate()` coincide exactamente con el definido en `Stack.Screen`? (es case-sensitive). 3) ¿La pantalla destino está definida dentro del mismo navegador desde el que navegas?

Checklist de Dominio

Para verificar que has comprendido y puedes implementar la navegación con React Navigation, asegúrate de poder realizar las siguientes tareas:

  • Instalar y configurar React Navigation y un Stack Navigator en un proyecto de Expo desde cero.
  • Configurar un NavigationContainer y definir al menos dos pantallas dentro de un Stack.Navigator.
  • Navegar de una pantalla a otra utilizando el método navigation.navigate() desde un evento (onPress).
  • Pasar parámetros complejos (objetos, arrays) entre pantallas y acceder a ellos de forma segura en la pantalla destino.
  • Implementar botones o gestos para volver a la pantalla anterior (navigation.goBack()) y para ir a la primera pantalla de la pila (navigation.popToTop()).
  • Personalizar el header de una pantalla (título, botones) tanto de forma estática (en las options del Stack.Screen) como dinámica (usando navigation.setOptions).
  • Manejar correctamente el caso en que una pantalla pueda ser abierta con o sin parámetros, sin que la aplicación se caiga.
  • Explicar la diferencia práctica entre los métodos navigate y push del objeto de navegación.
Falar no WhatsApp
Laboratorio de práctica

Antes de marcar esta lección como completa, escribí una evidencia breve para Desarrollo de Apps Nativas con React Native y Expo: De Cero a Producción: un ejemplo, una decisión, una captura, una mini demo o una nota que puedas reutilizar en portfolio.

Reflexión rápida

¿Qué cambiarías en tu forma de trabajar después de aplicar implementación de navegación con react navigation?

De lección a portfolio

Convertí esta lección en una prueba técnica visible.

Una app pequeña publicada, con README y decisiones explicadas, funciona mejor que una lista de tecnologías sueltas.

Paso 1

Creá una demo mínima que use el concepto de la lección.

Paso 2

Escribí un README corto con objetivo, stack, decisión técnica y mejora futura.

Paso 3

Publicá la demo y enlazala desde tu perfil profesional.

Newsletter Cursalo

Recibí rutas y cursos nuevos

Sumate para recibir recursos orientados a empleo y portfolio.

  • Rutas de empleo
  • Cursos prácticos
  • Portfolio y entrevistas

Sin spam. También podés entrar con tu cuenta para guardar progreso. Iniciá sesión

Implementación de Navegación con React Navigation | Cursalo