Guía 2: Navegación de la aplicación

React Native con Expo - App móvil de inventario

"Una app móvil completa no vive en una sola pantalla: necesita moverse entre secciones."

Introducción Objetivo Instalación Estructura App.js Drawer Tabs Stack Pantallas ProductCard HomeScreen Actividad

1) Introducción

En la guía anterior creamos la base visual de nuestra aplicación de inventario. Ahora agregaremos navegación entre pantallas.

La aplicación comenzará a parecerse más a una app real, ya que tendrá menú lateral, menú inferior y pantallas de detalle.

Drawer Navigator

Es el menú lateral de la app. Se abre desde un botón o deslizando desde el borde.

Menú lateral

Bottom Tabs

Es el menú inferior que permite cambiar rápidamente entre secciones principales.

Menú inferior

Stack Navigator

Permite avanzar de una pantalla a otra, por ejemplo de una lista al detalle.

Pantalla de detalle
En esta guía todavía no implementaremos el CRUD completo. Primero prepararemos la estructura de navegación que usaremos para categorías, productos y detalles.

2) Objetivo de la guía

Al finalizar esta guía, la aplicación tendrá varias pantallas conectadas entre sí.

En esta guía aprenderás a:

  • Instalar React Navigation en un proyecto de Expo.
  • Configurar NavigationContainer.
  • Crear un menú lateral usando Drawer.
  • Crear navegación inferior usando Bottom Tabs.
  • Crear navegación de pila usando Stack.
  • Enviar información de un producto a una pantalla de detalle.
  • Preparar la app para el CRUD de categorías y productos.

Mapa de navegación que construiremos

Drawer

  • Principal
  • Configuración

Bottom Tabs

  • Inicio
  • Productos
  • Categorías
  • Perfil

Stack

  • Lista de productos
  • Detalle de producto

3) Instalación de React Navigation

Primero instalaremos las librerías necesarias para que la app pueda navegar entre pantallas.

Paso 1: Instalar el paquete principal

Abre la terminal dentro de la carpeta del proyecto:

Terminal
cd inventario-app

Ahora instala el paquete principal de React Navigation:

Terminal
npm install @react-navigation/native

Paso 2: Instalar dependencias para Expo

Estas dependencias ayudan a que la navegación funcione correctamente en dispositivos móviles.

Terminal
npx expo install react-native-screens react-native-safe-area-context

Paso 3: Instalar Stack, Tabs y Drawer

Ahora instalaremos los tres tipos de navegación que usaremos en la aplicación.

Terminal
npm install @react-navigation/native-stack @react-navigation/bottom-tabs @react-navigation/drawer

Paso 4: Instalar dependencias del Drawer

El menú lateral necesita algunas librerías adicionales para gestos y animaciones.

Terminal
npx expo install react-native-gesture-handler react-native-reanimated react-native-worklets

Paso 5: Reiniciar Expo limpiando caché

Cuando se instalan librerías de navegación o animación, es recomendable reiniciar Expo limpiando la caché.

Terminal
npx expo start -c
Si Expo ya estaba ejecutándose, detén el servidor con Ctrl + C y luego vuelve a iniciarlo con el comando anterior.

4) Nueva estructura de carpetas

En la guía anterior ya teníamos carpetas para pantallas y componentes. Ahora agregaremos una carpeta para la navegación.

Estructura esperada

inventario-app/
├── App.js
├── src/
│ ├── components/
│ │ ├── CategoryPill.js
│ │ ├── ProductCard.js
│ │ └── StatCard.js
│ ├── navigation/
│ │ ├── RootDrawer.js
│ │ ├── MainTabs.js
│ │ └── ProductsStack.js
│ └── screens/
│ ├── HomeScreen.js
│ ├── ProductsScreen.js
│ ├── ProductDetailScreen.js
│ ├── CategoriesScreen.js
│ ├── ProfileScreen.js
│ └── SettingsScreen.js
└── package.json

Crear la carpeta navigation

Terminal
mkdir src/navigation

También crea los archivos que usaremos para organizar la navegación:

Archivos nuevos
src/navigation/RootDrawer.js
src/navigation/MainTabs.js
src/navigation/ProductsStack.js

5) Preparar el archivo App.js

El archivo App.js será el encargado de cargar la navegación general de la aplicación.

Paso 1: Importar Gesture Handler

Para que el Drawer funcione correctamente, agregaremos esta línea al inicio del archivo:

App.js
import 'react-native-gesture-handler';

Esta línea debe estar arriba de las demás importaciones.

Paso 2: Importar NavigationContainer

El componente NavigationContainer envolverá toda la navegación de la app.

App.js
import { NavigationContainer } from '@react-navigation/native';

Paso 3: Importar el Drawer principal

Más adelante crearemos el archivo RootDrawer.js. Por ahora lo importaremos en App.js.

App.js
import RootDrawer from './src/navigation/RootDrawer';

Paso 4: Construir App.js paso a paso

Vamos a reemplazar el contenido de App.js, pero lo haremos paso a paso.

Paso 4.1: Agregar las importaciones básicas

Importaciones iniciales
import 'react-native-gesture-handler';

import { StatusBar } from 'expo-status-bar';
import { NavigationContainer } from '@react-navigation/native';
import { SafeAreaProvider } from 'react-native-safe-area-context';

import RootDrawer from './src/navigation/RootDrawer';

Estas importaciones traen:

Paso 4.2: Crear el componente App

Estructura base de App
export default function App() {
  return (
    <SafeAreaProvider>
      <NavigationContainer>
        <RootDrawer />
      </NavigationContainer>
    </SafeAreaProvider>
  );
}

La estructura es: SafeAreaProvider envuelve NavigationContainer, que a su vez envuelve RootDrawer.

Paso 4.3: Agregar la barra de estado

App.js completo
import 'react-native-gesture-handler';

import { StatusBar } from 'expo-status-bar';
import { NavigationContainer } from '@react-navigation/native';
import { SafeAreaProvider } from 'react-native-safe-area-context';

import RootDrawer from './src/navigation/RootDrawer';

export default function App() {
  return (
    <SafeAreaProvider>
      <NavigationContainer>
        <RootDrawer />
      </NavigationContainer>

      <StatusBar style="light" />
    </SafeAreaProvider>
  );
}
¿Por qué SafeAreaProvider?

Ayuda a que el contenido respete las zonas seguras del dispositivo, como notches, barras superiores o navegación inferior.

6) Crear el Drawer Navigator

El Drawer será el menú lateral principal de la app. Desde aquí podremos acceder a la sección principal y a configuración.

Abre el archivo:

src/navigation/RootDrawer.js

Paso 1: Importar createDrawerNavigator

src/navigation/RootDrawer.js
import { createDrawerNavigator } from '@react-navigation/drawer';

Paso 2: Importar pantallas o navegadores hijos

El Drawer no cargará directamente todas las pantallas. Cargará un navegador de tabs llamado MainTabs y una pantalla de configuración.

src/navigation/RootDrawer.js
import MainTabs from './MainTabs';
import SettingsScreen from '../screens/SettingsScreen';

Paso 3: Crear el objeto Drawer

src/navigation/RootDrawer.js
const Drawer = createDrawerNavigator();

Paso 4: Crear el navegador Drawer paso a paso

Paso 4.1: Estructura básica

RootDrawer básico
export default function RootDrawer() {
  return (
    <Drawer.Navigator>
      <Drawer.Screen
        name="MainTabs"
        component={MainTabs}
      />

      <Drawer.Screen
        name="Settings"
        component={SettingsScreen}
      />
    </Drawer.Navigator>
  );
}

Esto crea un menú lateral con dos opciones: Principal (MainTabs) y Configuración (Settings).

Paso 4.2: Personalizar los colores del Drawer

Ahora agregaremos opciones visuales al Drawer.Navigator:

Drawer personalizado
<Drawer.Navigator
  screenOptions={{
    headerShown: false,
    drawerActiveTintColor: '#1a5276',
    drawerInactiveTintColor: '#64748b',
    drawerLabelStyle: {
      fontWeight: '800',
    },
  }}
>

Estos atributos controlan:

Paso 4.3: Agregar opciones individuales a cada pantalla

Para que el menú lateral muestre nombres bonitos, agregamos options a cada Drawer.Screen:

Pantallas con opciones
      <Drawer.Screen
        name="MainTabs"
        component={MainTabs}
        options={{
          title: 'Principal',
          drawerLabel: 'Principal',
        }}
      />

      <Drawer.Screen
        name="Settings"
        component={SettingsScreen}
        options={{
          title: 'Configuración',
          drawerLabel: 'Configuración',
        }}
      />

Paso 5: Código final de RootDrawer.js

Vista previa del menú Drawer

El menú lateral (Drawer) se vería de la siguiente manera cuando lo abres:

Menú de navegación

Principal
Configuración

El contenido se oscurece cuando abre el Drawer

7) Crear el Bottom Tabs Navigator

El Bottom Tabs Navigator será el menú inferior de la aplicación. Este menú permitirá moverse rápidamente entre las secciones principales.

Abre el archivo:

src/navigation/MainTabs.js

Paso 1: Importar createBottomTabNavigator

src/navigation/MainTabs.js
import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';

Paso 2: Importar Text y Pressable

Usaremos Text para mostrar pequeños íconos usando emojis y Pressable para crear el botón del menú lateral.

src/navigation/MainTabs.js
import { Text, Pressable } from 'react-native';

Paso 3: Importar las pantallas

src/navigation/MainTabs.js
import HomeScreen from '../screens/HomeScreen';
import CategoriesScreen from '../screens/CategoriesScreen';
import ProfileScreen from '../screens/ProfileScreen';
import ProductsStack from './ProductsStack';

Paso 4: Crear el objeto Tab

src/navigation/MainTabs.js
const Tab = createBottomTabNavigator();

Paso 5: Crear un botón para abrir el Drawer

Como ocultamos el encabezado del Drawer, crearemos nuestro propio botón.

Botón de menú
function MenuButton({ navigation }) {
  return (
    <Pressable
      onPress={() => navigation.getParent()?.openDrawer()}
      style={{ marginLeft: 16 }}
    >
      <Text style={{ color: '#ffffff', fontSize: 24 }}>☰</Text>
    </Pressable>
  );
}
¿Qué hace navigation.getParent()?

La pantalla actual está dentro de los tabs, y los tabs están dentro del drawer. Por eso usamos getParent() para acceder al navegador padre y abrir el menú lateral.

Paso 6: Crear el navegador de Tabs paso a paso

Paso 6.1: Estructura básica

MainTabs básico
export default function MainTabs() {
  return (
    <Tab.Navigator>
      <Tab.Screen name="Inicio" component={HomeScreen} />
      <Tab.Screen name="Productos" component={ProductsStack} />
      <Tab.Screen name="Categorias" component={CategoriesScreen} />
      <Tab.Screen name="Perfil" component={ProfileScreen} />
    </Tab.Navigator>
  );
}

Aquí registramos las 4 pantallas principales que aparecerán en el menú inferior.

Paso 6.2: Personalizar el encabezado

Agregamos estilos para que el encabezado (que viene de los tabs) sea azul oscuro:

screenOptions paso a paso
screenOptions={({ navigation }) => ({
  headerStyle: {
    backgroundColor: '#1a5276',
  },
  headerTintColor: '#ffffff',
  headerTitleStyle: {
    fontWeight: '900',
  },
  headerLeft: () => <MenuButton navigation={navigation} />,

Esto controla el color del encabezado, el color del texto, y coloca un botón de menú en la esquina izquierda.

Paso 6.3: Personalizar la barra inferior de tabs

Estilos de la barra inferior
  tabBarActiveTintColor: '#1a5276',
  tabBarInactiveTintColor: '#64748b',
  tabBarLabelStyle: {
    fontWeight: '800',
  },
  tabBarStyle: {
    height: 64,
    paddingBottom: 8,
    paddingTop: 8,
  },
})}

Esto hace que la barra inferior sea más alta, con texto más grueso, y con colores azul (activo) y gris (inactivo).

Paso 6.4: Agregar íconos y nombres a cada tab

Para cada pantalla, agregamos un emoji como ícono y un nombre:

Ejemplo de options en una pantalla
<Tab.Screen
  name="Inicio"
  component={HomeScreen}
  options={{
    title: 'Inicio',
    tabBarIcon: () => <Text>🏠</Text>,
  }}
/>

Usamos emojis para los íconos en lugar de una librería adicional.

Paso 7: Código final de MainTabs.js

Vista previa de la navegación con Tabs

La barra de tabs se verá de la siguiente manera cuando hagas tap en cada pestaña:

Inventario App

Contenido de la pantalla activa

🏠
Inicio
📦
Productos
🏷️
Categorías
👤
Perfil

8) Crear Stack para productos

Ahora crearemos una navegación de tipo Stack para productos. Esto permitirá pasar de la lista de productos a una pantalla de detalle.

Abre el archivo:

src/navigation/ProductsStack.js

Paso 1: Importar createNativeStackNavigator

src/navigation/ProductsStack.js
import { createNativeStackNavigator } from '@react-navigation/native-stack';

Paso 2: Importar las pantallas del Stack

src/navigation/ProductsStack.js
import ProductsScreen from '../screens/ProductsScreen';
import ProductDetailScreen from '../screens/ProductDetailScreen';

Paso 3: Crear el objeto Stack

src/navigation/ProductsStack.js
const Stack = createNativeStackNavigator();

Paso 4: Crear el Stack paso a paso

Paso 4.1: Estructura básica

El Stack Navigator maneja dos pantallas:

ProductsStack básico
export default function ProductsStack() {
  return (
    <Stack.Navigator>
      <Stack.Screen
        name="ProductosLista"
        component={ProductsScreen}
      />

      <Stack.Screen
        name="DetalleProducto"
        component={ProductDetailScreen}
      />
    </Stack.Navigator>
  );
}

Paso 4.2: Ocultar el encabezado del Stack

Aunque los tabs ya tienen un encabezado superior, el Stack Navigator crearía otro encabezado. Para evitar duplicarlo, lo ocultamos:

Stack.Navigator con opciones
<Stack.Navigator
  screenOptions={{
    headerShown: false,
  }}
>

Ahora solo habrá un encabezado (el de los tabs), y el Stack Navigator simplemente administra la navegación en segundo plano.

Paso 5: Código final de ProductsStack.js

Vista previa de la lista de productos

La pantalla de productos (ProductsScreen) mostrará una lista de productos como esta:

Productos

Laptop Dell XPS

$850.00 - Stock: 8

Tecnología
Mouse inalámbrico

$18.50 - Stock: 25

Accesorios
Silla ejecutiva

$95.00 - Stock: 4

Oficina

9) Crear las nuevas pantallas

Ahora crearemos las pantallas que se usarán en la navegación.

Pantalla de productos paso a paso

Crea el archivo:

src/screens/ProductsScreen.js

Paso 1: Importar y crear datos

Primero importamos lo necesario:

Importaciones
import { useState } from 'react';
import { ScrollView, View, Text, StyleSheet } from 'react-native';

import ProductCard from '../components/ProductCard';

Luego creamos datos temporales dentro de la función:

Datos en ProductsScreen
export default function ProductsScreen({ navigation }) {
  const [categorias] = useState([
    { id: 1, nombre: 'Tecnología' },
    { id: 2, nombre: 'Accesorios' },
    { id: 3, nombre: 'Oficina' },
  ]);

  const [productos] = useState([
    {
      id: 1,
      nombre: 'Laptop Dell',
      precio: 850,
      stock: 8,
      categoriaId: 1,
    },
    {
      id: 2,
      nombre: 'Mouse inalámbrico',
      precio: 18.5,
      stock: 25,
      categoriaId: 2,
    },
    {
      id: 3,
      nombre: 'Silla ejecutiva',
      precio: 95,
      stock: 4,
      categoriaId: 3,
    },
  ]);

Nota que la función recibe { navigation } como parámetro. Esto nos permite navegar hacia otras pantallas.

Paso 2: Crear función auxiliar para categorías

Función para buscar categoría
  function obtenerNombreCategoria(categoriaId) {
    const categoriaEncontrada = categorias.find(
      categoria => categoria.id === categoriaId
    );

    return categoriaEncontrada ? categoriaEncontrada.nombre : 'Sin categoría';
  }

Paso 3: Crear el UI de la pantalla

Primero, un encabezado simple:

Encabezado de la pantalla
  return (
    <ScrollView style={styles.container} contentContainerStyle={styles.content}>
      <View style={styles.headerBlock}>
        <Text style={styles.title}>Productos</Text>
        <Text style={styles.subtitle}>
          Consulta los productos registrados en el inventario.
        </Text>
      </View>

Paso 4: Mostrar los productos con navegación

Finalmente, listamos los productos. Cada uno es clickeable y abre el detalle:

Listado con navegación
      {productos.map(producto => (
        <ProductCard
          key={producto.id}
          producto={producto}
          categoria={obtenerNombreCategoria(producto.categoriaId)}
          onPress={() =>
            navigation.navigate('DetalleProducto', {
              producto: producto,
              categoria: obtenerNombreCategoria(producto.categoriaId),
            })
          }
        />
      ))}
    </ScrollView>
  );
}

La parte importante es navigation.navigate('DetalleProducto', {...}). Esto navega a la pantalla de detalle y le pasa el producto como parámetro.

Código final de ProductsScreen.js

Pantalla de detalle de producto paso a paso

Crea el archivo:

src/screens/ProductDetailScreen.js

Paso 1: Recibir parámetros y crear la estructura

Esta pantalla recibirá el producto y la categoría a través de route.params.

Importaciones y parámetros
import { View, Text, StyleSheet, Pressable } from 'react-native';

export default function ProductDetailScreen({ route, navigation }) {
  const { producto, categoria } = route.params;

Paso 2: Crear la tarjeta con el encabezado

Ahora mostramos la información del producto en una tarjeta:

Estructura inicial
  return (
    <View style={styles.container}>
      <View style={styles.card}>
        <Text style={styles.kicker}>Detalle del producto</Text>
        <Text style={styles.title}>{producto.nombre}</Text>

Paso 3: Agregar los campos de información

Luego agregamos recuadros para mostrar cada detalle:

Información del producto
        <View style={styles.infoBox}>
          <Text style={styles.label}>Categoría</Text>
          <Text style={styles.value}>{categoria}</Text>
        </View>

        <View style={styles.infoBox}>
          <Text style={styles.label}>Precio</Text>
          <Text style={styles.value}>${producto.precio.toFixed(2)}</Text>
        </View>

        <View style={styles.infoBox}>
          <Text style={styles.label}>Stock disponible</Text>
          <Text style={styles.value}>{producto.stock} unidades</Text>
        </View>

Paso 4: Agregar botón de navegación

Finalmente, un botón que regresa a la lista de productos:

Botón y cierre
        <Pressable style={styles.button} onPress={() => navigation.goBack()}>
          <Text style={styles.buttonText}>Volver a productos</Text>
        </Pressable>
      </View>
    </View>
  );
}
src/screens/ProductDetailScreen.js
import { View, Text, StyleSheet, Pressable } from 'react-native';

export default function ProductDetailScreen({ route, navigation }) {
  const { producto, categoria } = route.params;

  return (
    <View style={styles.container}>
      <View style={styles.card}>
        <Text style={styles.kicker}>Detalle del producto</Text>

        <Text style={styles.title}>{producto.nombre}</Text>

        <View style={styles.infoBox}>
          <Text style={styles.label}>Categoría</Text>
          <Text style={styles.value}>{categoria}</Text>
        </View>

        <View style={styles.infoBox}>
          <Text style={styles.label}>Precio</Text>
          <Text style={styles.value}>${producto.precio.toFixed(2)}</Text>
        </View>

        <View style={styles.infoBox}>
          <Text style={styles.label}>Stock disponible</Text>
          <Text style={styles.value}>{producto.stock} unidades</Text>
        </View>

        <Pressable style={styles.button} onPress={() => navigation.goBack()}>
          <Text style={styles.buttonText}>Volver a productos</Text>
        </Pressable>
      </View>
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#f8fafc',
    padding: 20,
  },
  card: {
    backgroundColor: '#ffffff',
    borderRadius: 22,
    padding: 22,
    borderWidth: 1,
    borderColor: '#e2e8f0',
  },
  kicker: {
    color: '#1a5276',
    fontWeight: '900',
    textTransform: 'uppercase',
    fontSize: 12,
    marginBottom: 8,
  },
  title: {
    fontSize: 28,
    fontWeight: '900',
    color: '#0f172a',
    marginBottom: 18,
  },
  infoBox: {
    backgroundColor: '#f8fafc',
    padding: 14,
    borderRadius: 16,
    marginBottom: 12,
  },
  label: {
    color: '#64748b',
    fontWeight: '800',
    fontSize: 13,
  },
  value: {
    color: '#0f172a',
    fontSize: 18,
    fontWeight: '900',
    marginTop: 4,
  },
  button: {
    backgroundColor: '#1a5276',
    padding: 14,
    borderRadius: 14,
    marginTop: 10,
  },
  buttonText: {
    color: '#ffffff',
    textAlign: 'center',
    fontWeight: '900',
  },
});

Pantalla de categorías

Crea el archivo:

src/screens/CategoriesScreen.js
src/screens/CategoriesScreen.js
import { useState } from 'react';
import { ScrollView, View, Text, StyleSheet } from 'react-native';

export default function CategoriesScreen() {
  const [categorias] = useState([
    {
      id: 1,
      nombre: 'Tecnología',
      descripcion: 'Equipos electrónicos y computadoras',
    },
    {
      id: 2,
      nombre: 'Accesorios',
      descripcion: 'Complementos para computadoras y oficina',
    },
    {
      id: 3,
      nombre: 'Oficina',
      descripcion: 'Mobiliario y herramientas de trabajo',
    },
  ]);

  return (
    <ScrollView style={styles.container} contentContainerStyle={styles.content}>
      <Text style={styles.title}>Categorías</Text>
      <Text style={styles.subtitle}>
        Clasifica los productos del inventario.
      </Text>

      {categorias.map(categoria => (
        <View key={categoria.id} style={styles.card}>
          <Text style={styles.categoryName}>{categoria.nombre}</Text>
          <Text style={styles.description}>{categoria.descripcion}</Text>
        </View>
      ))}
    </ScrollView>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#f8fafc',
  },
  content: {
    padding: 20,
    paddingBottom: 40,
  },
  title: {
    fontSize: 28,
    fontWeight: '900',
    color: '#0f172a',
  },
  subtitle: {
    color: '#64748b',
    marginTop: 6,
    marginBottom: 18,
    fontSize: 15,
  },
  card: {
    backgroundColor: '#ffffff',
    padding: 18,
    borderRadius: 18,
    marginBottom: 12,
    borderWidth: 1,
    borderColor: '#e2e8f0',
  },
  categoryName: {
    fontSize: 18,
    fontWeight: '900',
    color: '#1a5276',
  },
  description: {
    color: '#64748b',
    marginTop: 5,
  },
});

Pantalla de perfil

Crea el archivo:

src/screens/ProfileScreen.js
src/screens/ProfileScreen.js
import { View, Text, StyleSheet } from 'react-native';

export default function ProfileScreen() {
  return (
    <View style={styles.container}>
      <View style={styles.card}>
        <View style={styles.avatar}>
          <Text style={styles.avatarText}>AD</Text>
        </View>

        <Text style={styles.title}>Administrador</Text>
        <Text style={styles.subtitle}>
          Usuario encargado de gestionar el inventario.
        </Text>

        <View style={styles.infoBox}>
          <Text style={styles.label}>Rol</Text>
          <Text style={styles.value}>Encargado de inventario</Text>
        </View>

        <View style={styles.infoBox}>
          <Text style={styles.label}>Módulo actual</Text>
          <Text style={styles.value}>Productos y categorías</Text>
        </View>
      </View>
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#f8fafc',
    padding: 20,
  },
  card: {
    backgroundColor: '#ffffff',
    borderRadius: 22,
    padding: 22,
    borderWidth: 1,
    borderColor: '#e2e8f0',
    alignItems: 'center',
  },
  avatar: {
    width: 84,
    height: 84,
    borderRadius: 42,
    backgroundColor: '#1a5276',
    justifyContent: 'center',
    alignItems: 'center',
    marginBottom: 14,
  },
  avatarText: {
    color: '#ffffff',
    fontSize: 26,
    fontWeight: '900',
  },
  title: {
    fontSize: 24,
    fontWeight: '900',
    color: '#0f172a',
  },
  subtitle: {
    textAlign: 'center',
    color: '#64748b',
    marginTop: 6,
    marginBottom: 18,
  },
  infoBox: {
    width: '100%',
    backgroundColor: '#f8fafc',
    padding: 14,
    borderRadius: 16,
    marginBottom: 10,
  },
  label: {
    color: '#64748b',
    fontWeight: '800',
    fontSize: 13,
  },
  value: {
    color: '#0f172a',
    fontWeight: '900',
    marginTop: 4,
  },
});

Pantalla de configuración

Crea el archivo:

src/screens/SettingsScreen.js
src/screens/SettingsScreen.js
import { View, Text, StyleSheet, Pressable } from 'react-native';

export default function SettingsScreen({ navigation }) {
  return (
    <View style={styles.container}>
      <View style={styles.topbar}>
        <Pressable onPress={() => navigation.openDrawer()}>
          <Text style={styles.menuButton}>☰</Text>
        </Pressable>

        <Text style={styles.topbarTitle}>Configuración</Text>
      </View>

      <View style={styles.card}>
        <Text style={styles.title}>Ajustes de la aplicación</Text>
        <Text style={styles.subtitle}>
          Esta sección servirá más adelante para configurar opciones generales
          del sistema de inventario.
        </Text>

        <View style={styles.option}>
          <Text style={styles.optionTitle}>Nombre de la empresa</Text>
          <Text style={styles.optionText}>Inventario App</Text>
        </View>

        <View style={styles.option}>
          <Text style={styles.optionTitle}>Moneda</Text>
          <Text style={styles.optionText}>Dólares estadounidenses</Text>
        </View>
      </View>
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#f8fafc',
  },
  topbar: {
    backgroundColor: '#1a5276',
    paddingTop: 48,
    paddingHorizontal: 20,
    paddingBottom: 16,
    flexDirection: 'row',
    alignItems: 'center',
    gap: 14,
  },
  menuButton: {
    color: '#ffffff',
    fontSize: 26,
  },
  topbarTitle: {
    color: '#ffffff',
    fontSize: 20,
    fontWeight: '900',
  },
  card: {
    backgroundColor: '#ffffff',
    margin: 20,
    padding: 22,
    borderRadius: 22,
    borderWidth: 1,
    borderColor: '#e2e8f0',
  },
  title: {
    fontSize: 24,
    fontWeight: '900',
    color: '#0f172a',
  },
  subtitle: {
    color: '#64748b',
    marginTop: 8,
    marginBottom: 18,
  },
  option: {
    backgroundColor: '#f8fafc',
    padding: 14,
    borderRadius: 16,
    marginBottom: 10,
  },
  optionTitle: {
    color: '#0f172a',
    fontWeight: '900',
  },
  optionText: {
    color: '#64748b',
    marginTop: 4,
  },
});

10) Modificar ProductCard para permitir clic

En la guía anterior, ProductCard solo mostraba información. Ahora necesitamos que sea clickeable para abrir el detalle del producto.

Abre el archivo:

src/components/ProductCard.js

Paso 1: Actualizar importación

Antes importábamos:

Importación anterior
import { View, Text, StyleSheet } from 'react-native';

Ahora necesitamos importar Pressable:

Importación actualizada
import { Pressable, View, Text, StyleSheet } from 'react-native';

Paso 2: Recibir la prop onPress

Antes la función era:

Función anterior
export default function ProductCard({ producto, categoria }) {

Ahora recibiremos una prop onPress que ejecutará cuando se presione:

Función actualizada
export default function ProductCard({ producto, categoria, onPress }) {

Paso 3: Cambiar View por Pressable

El contenedor principal (que antes era View) ahora será Pressable:

Cambio de contenedor
<Pressable style={styles.card} onPress={onPress}>
  // ... resto del contenido ...
</Pressable>

El onPress={onPress} hace que cuando se toque la tarjeta, se ejecute la función que pasó el componente padre (ProductsScreen).

Código final de ProductCard.js

11) Actualizar HomeScreen para navegar

En la Guía 1, HomeScreen mostraba un inicio visual. Ahora agregaremos botones para navegar a productos y categorías.

Paso 1: Recibir navigation

Para poder navegar, la función debe recibir navigation:

Anterior
export default function HomeScreen() {
Ahora
export default function HomeScreen({ navigation }) {

Paso 2: Importar Pressable

En las importaciones de React Native, necesitamos Pressable:

Importación anterior
import { ScrollView, View, Text, StyleSheet } from 'react-native';
Importación actualizada
import { ScrollView, View, Text, StyleSheet, Pressable } from 'react-native';

Paso 3: Crear contenedor de botones

Debajo del bloque del encabezado, agrega un View para los botones:

Inicio del contenedor
<View style={styles.actionsRow}>

Paso 4: Agregar botón de productos

El primer botón navega a la pantalla de productos:

Botón 1: Productos
  <Pressable
    style={styles.primaryButton}
    onPress={() => navigation.navigate('Productos')}
  >
    <Text style={styles.primaryButtonText}>Ver productos</Text>
  </Pressable>

Paso 5: Agregar botón de categorías

El segundo botón navega a la pantalla de categorías:

Botón 2: Categorías
  <Pressable
    style={styles.secondaryButton}
    onPress={() => navigation.navigate('Categorias')}
  >
    <Text style={styles.secondaryButtonText}>Ver categorías</Text>
  </Pressable>
</View>

Paso 6: Agregar estilos de los botones

En la sección de estilos, agrega estos nuevos estilos:

Estilos de acciones
actionsRow: {
  flexDirection: 'row',
  gap: 10,
  marginBottom: 18,
},
primaryButton: {
  flex: 1,
  backgroundColor: '#1a5276',
  padding: 14,
  borderRadius: 14,
},
primaryButtonText: {
  color: '#ffffff',
  textAlign: 'center',
  fontWeight: '900',
},
secondaryButton: {
  flex: 1,
  backgroundColor: '#e0f2fe',
  padding: 14,
  borderRadius: 14,
},
secondaryButtonText: {
  color: '#1a5276',
  textAlign: 'center',
  fontWeight: '900',
},
Recordatorio: No reescritas completa HomeScreen. Solo:
  • Agrega { navigation } a la función.
  • Importa Pressable.
  • Coloca el bloque de botones debajo del encabezado.
  • Agrega los estilos nuevos al StyleSheet.

12) Actividad práctica

Ahora es tu turno. Realiza las siguientes modificaciones.

Ejercicio 1

Cambia los nombres de las opciones del Drawer. Por ejemplo: Principal por Inicio del sistema.

Ejercicio 2

Cambia los emojis usados como íconos de los tabs.

Ejercicio 3

Agrega una nueva pantalla llamada AboutScreen.js y colócala dentro del Drawer.

Ejercicio 4

Agrega un cuarto producto temporal y verifica que también pueda abrirse en la pantalla de detalle.

Checklist de revisión

En la siguiente guía construiremos el CRUD local para categorías y productos. Usaremos formularios, estado, creación, edición y eliminación de registros.