React es hoy la biblioteca más utilizada para construir interfaces de usuario en la web, y entender qué problema resuelve es mucho más importante que memorizar su API. Antes de escribir una sola línea de código conviene tener claro por qué miles de equipos abandonaron la manipulación manual del DOM y adoptaron un modelo declarativo basado en componentes. En esta lección verás ese contraste con un ejemplo real, conocerás el vocabulario básico de React y descubrirás CicloUrbano, la aplicación de alquiler de bicicletas que construirás a lo largo de todo el curso.
Contenido
- El problema: manipular el DOM a mano
- La misma pantalla con React: el enfoque declarativo
- Qué es exactamente React (y qué no es)
- La interfaz como función del estado
- Historia mínima y estado actual
- El vocabulario que verás a partir de ahora
- Cuándo React encaja y cuándo no
- Presentación del proyecto: CicloUrbano
- El problema: manipular el DOM a mano
Imagina una pantalla muy sencilla de CicloUrbano: un listado de bicicletas con su modelo, su estado y su precio por hora, y un filtro que permita ver solo las disponibles. Con JavaScript puro y manipulación directa del DOM, el código se parece a esto.
// catalogo.js — versión con JavaScript puro y manipulación directa del DOM
const bicicletas = [
{ id: 'bici-001', modelo: 'Urbana Clásica', tipo: 'urbana', estado: 'disponible', precioHora: 2.5 },
{ id: 'bici-002', modelo: 'Eléctrica Pro', tipo: 'electrica', estado: 'alquilada', precioHora: 4 },
{ id: 'bici-003', modelo: 'Carga Max', tipo: 'carga', estado: 'mantenimiento', precioHora: 5.5 }
];
let soloDisponibles = false;
const contenedor = document.getElementById('catalogo');
const boton = document.getElementById('filtro');
const contador = document.getElementById('contador');
function pintarCatalogo() {
// 1. Hay que vaciar a mano lo que ya había pintado
contenedor.innerHTML = '';
// 2. Hay que decidir a mano qué se muestra
const visibles = soloDisponibles
? bicicletas.filter((b) => b.estado === 'disponible')
: bicicletas;
// 3. Hay que construir cada nodo del DOM paso a paso
visibles.forEach((bicicleta) => {
const tarjeta = document.createElement('article');
tarjeta.className = 'tarjeta-bicicleta';
const titulo = document.createElement('h3');
titulo.textContent = bicicleta.modelo;
const estado = document.createElement('span');
estado.className = 'estado estado--' + bicicleta.estado;
estado.textContent = bicicleta.estado;
const precio = document.createElement('p');
precio.textContent = bicicleta.precioHora.toFixed(2) + ' €/h';
tarjeta.append(titulo, estado, precio);
contenedor.append(tarjeta);
});
// 4. Y hay que acordarse de actualizar TODO lo demás que dependa de los datos
contador.textContent = visibles.length + ' bicicletas';
}
boton.addEventListener('click', () => {
soloDisponibles = !soloDisponibles;
boton.textContent = soloDisponibles ? 'Ver todas' : 'Solo disponibles';
pintarCatalogo();
});
pintarCatalogo();Este código funciona. El problema no es que sea largo, sino qué le pasa cuando la aplicación crece:
- Sincronización manual. Los datos viven en
bicicletasysoloDisponibles, pero la pantalla vive en el DOM. Nada garantiza que estén de acuerdo: eres tú quien debe llamar apintarCatalogo()en el momento exacto. El día que un compañero añada una acción nueva y olvide esa llamada, la pantalla mostrará información desfasada. - Instrucciones, no descripciones. El código no dice cómo debe verse la pantalla; dice qué pasos hay que dar para llegar a ella (
createElement,append,textContent...). Leerlo obliga a simular mentalmente su ejecución. - El borrado y repintado completo es tosco.
contenedor.innerHTML = ''destruye y recrea todo: se pierde el foco del teclado, la posición del scroll y el estado de cualquier campo de formulario que hubiera dentro. - Complejidad multiplicativa. Con un filtro es asumible. Con un filtro, un buscador, una ordenación, un contador, un badge de estación y un botón de reserva, el número de combinaciones que hay que mantener coherentes crece mucho más rápido que el número de funcionalidades.
- La misma pantalla con React: el enfoque declarativo
Ahora la misma funcionalidad escrita con React. No hace falta que entiendas cada detalle todavía: fíjate solo en la forma del código.
// CatalogoBicicletas.jsx — versión con React
import { useState } from 'react';
const bicicletas = [
{ id: 'bici-001', modelo: 'Urbana Clásica', tipo: 'urbana', estado: 'disponible', precioHora: 2.5 },
{ id: 'bici-002', modelo: 'Eléctrica Pro', tipo: 'electrica', estado: 'alquilada', precioHora: 4 },
{ id: 'bici-003', modelo: 'Carga Max', tipo: 'carga', estado: 'mantenimiento', precioHora: 5.5 }
];
function CatalogoBicicletas() {
const [soloDisponibles, setSoloDisponibles] = useState(false);
const visibles = soloDisponibles
? bicicletas.filter((b) => b.estado === 'disponible')
: bicicletas;
return (
<section>
<button onClick={() => setSoloDisponibles(!soloDisponibles)}>
{soloDisponibles ? 'Ver todas' : 'Solo disponibles'}
</button>
<p>{visibles.length} bicicletas</p>
{visibles.map((bicicleta) => (
<article className="tarjeta-bicicleta" key={bicicleta.id}>
<h3>{bicicleta.modelo}</h3>
<span className={`estado estado--${bicicleta.estado}`}>{bicicleta.estado}</span>
<p>{bicicleta.precioHora.toFixed(2)} €/h</p>
</article>
))}
</section>
);
}
export default CatalogoBicicletas;Compara ambas versiones apartado por apartado:
| Aspecto | JavaScript puro (imperativo) | React (declarativo) |
|---|---|---|
| Qué escribes | Los pasos para modificar la pantalla | Cómo debe verse la pantalla para unos datos dados |
| Quién actualiza el DOM | Tú, con createElement, append, innerHTML |
React, comparando lo nuevo con lo anterior |
| Dónde vive la verdad | Repartida entre variables y el DOM | En el estado del componente, y solo ahí |
| Al cambiar un dato | Hay que recordar llamar a la función de repintado | React vuelve a ejecutar el componente automáticamente |
| Riesgo de desincronización | Alto y creciente | Prácticamente eliminado por diseño |
| Reutilizar la tarjeta en otra pantalla | Copiar y pegar la función que la construye | Extraer un componente y usarlo donde haga falta |
La diferencia clave está en una sola frase: en la versión imperativa describes transiciones; en la declarativa describes destinos. Tú declaras «con estos datos, la pantalla es así», y React se encarga de averiguar qué hay que tocar del DOM para llegar hasta ahí. Cómo lo averigua exactamente es el tema de la lección Cómo Renderiza React: Virtual DOM y Reconciliación.
- Qué es exactamente React (y qué no es)
React es una biblioteca de JavaScript para construir interfaces de usuario mediante componentes. Conviene desmenuzar esa definición:
- Biblioteca, no framework. React se ocupa de una cosa: producir y mantener actualizada la interfaz. No trae enrutador, ni cliente HTTP, ni sistema de formularios, ni gestor de estado global, ni convención de carpetas. Esas piezas las eliges tú del ecosistema (verás React Router en el Módulo 6 y Redux en el Módulo 7). Es más libertad y también más decisiones.
- Declarativa. Describes el resultado, no el procedimiento, como acabas de ver.
- Basada en componentes. La unidad de construcción es el componente: una función que devuelve un trozo de interfaz. Los componentes se anidan unos dentro de otros formando un árbol, igual que las etiquetas HTML, pero con la ventaja de que son piezas tuyas, con nombre propio, reutilizables y comprobables por separado.
- Agnóstica del destino. React describe la interfaz; quien la pinta es un renderizador.
react-domla pinta en el navegador, React Native la pinta con componentes nativos de iOS y Android (lo verás en 10-05) y hay renderizadores para terminal o PDF. Por eso el paquetereacty el paquetereact-domestán separados.
Lo que React no es: no es un lenguaje nuevo (es JavaScript), no es un sustituto de HTML y CSS (los necesitas igual), y no es una solución mágica de rendimiento (una aplicación React mal escrita puede ir más lenta que una página estática bien hecha).
- La interfaz como función del estado
La idea que sostiene todo React cabe en una expresión conceptual:
Es decir: la pantalla es el resultado de aplicar tus componentes a los datos actuales. Si el estado es «el filtro está desactivado y hay tres bicicletas», la pantalla es una y solo una. Si el estado cambia a «filtro activado», React vuelve a calcular la pantalla desde cero conceptualmente y actualiza el DOM real con las diferencias.
flowchart LR
A[Estado<br/>datos de la aplicación] --> B[Componentes<br/>funciones que describen la interfaz]
B --> C[Descripción de la interfaz]
C --> D[React actualiza el DOM real]
E[Interacción del usuario] --> F[Cambio de estado]
F --> A
Las consecuencias prácticas de este modelo son enormes:
- Solo hay una fuente de verdad. Si quieres saber por qué la pantalla se ve así, miras el estado. No hay un tercer sitio donde alguien haya modificado un
textContentpor su cuenta. - Depurar es más fácil. Reproducir un fallo se convierte en reproducir un estado.
- El flujo es predecible. Interacción → cambio de estado → nuevo render. Siempre en ese orden y siempre en esa dirección.
- Historia mínima y estado actual
| Año | Hito |
|---|---|
| 2011-2012 | Jordan Walke crea un prototipo interno en Facebook para resolver problemas de sincronización de interfaz en el feed y en los anuncios |
| 2013 | Publicación como software libre. JSX y el Virtual DOM generan escepticismo inicial |
| 2015 | React Native lleva el modelo a móviles nativos |
| 2016 | React 15: consolidación y adopción masiva en la industria |
| 2017 | React 16 («Fiber»): reescritura completa del motor interno, límites de error, fragmentos |
| 2019 | React 16.8 introduce los hooks: los componentes de función pueden tener estado y el modelo de clases queda relegado |
| 2022 | React 18: renderizado concurrente, createRoot, transiciones, Suspense en servidor |
| 2024-2025 | React 19: Server Components estables, nuevas APIs de acciones y formularios, compilador optimizador |
Datos que conviene tener presentes:
- Lo mantiene Meta junto a un amplio grupo de colaboradores externos, y se publica bajo licencia MIT.
- Es la tecnología de interfaz más demandada del mercado laboral web, lo que se traduce en abundancia de documentación, cursos, librerías de componentes y respuestas a problemas concretos.
- La documentación oficial (
react.dev) fue reescrita por completo alrededor de los hooks: si encuentras un tutorial lleno declass ... extends React.Component, casi con seguridad está desactualizado. En este curso los componentes de clase aparecen únicamente como código heredado que hay que saber leer (lección 02-02).
- El vocabulario que verás a partir de ahora
Estos cuatro términos vertebran el curso. Aquí solo los nombramos; cada uno tiene su lección.
| Concepto | En una frase | Dónde se estudia |
|---|---|---|
| Componente | Función que devuelve un trozo de interfaz y se reutiliza como una etiqueta propia | Módulo 2 |
| JSX | Sintaxis parecida a HTML que se escribe dentro de JavaScript para describir la interfaz | Lección 01-04 |
| Props | Datos que un componente padre pasa a un hijo; son de solo lectura | Lección 02-03 |
| Estado | Datos que un componente guarda entre renders y que, al cambiar, provocan un nuevo render | Lección 02-04 |
| Virtual DOM | Representación ligera de la interfaz en memoria que React compara para saber qué tocar del DOM real | Lección 01-05 |
- Cuándo React encaja y cuándo no
React brilla cuando la interfaz es rica en estado: muchos datos cambiando, muchas vistas que dependen de ellos y mucha interacción. Un panel de operario de CicloUrbano que muestre en tiempo real qué bicicletas están alquiladas es un caso de libro. Un folleto informativo de tres páginas estáticas, no.
| Opción | Modelo | Punto fuerte | A tener en cuenta |
|---|---|---|---|
| React | Biblioteca de componentes, declarativa | Ecosistema y comunidad enormes, empleabilidad, React Native | Hay que montar el resto del stack eligiendo librerías |
| Vue | Framework progresivo con plantillas | Curva de entrada suave, muy buena documentación | Comunidad menor que la de React |
| Angular | Framework completo y opinado, con TypeScript | Todo viene incluido y estandarizado; ideal en organizaciones grandes | Mucho más que aprender antes de ser productivo |
| Svelte | Compilador, sin runtime de Virtual DOM | Menos código y paquetes muy ligeros | Ecosistema y oferta laboral más reducidos |
| Sin framework | DOM + JavaScript estándar | Cero dependencias, máximo control, carga mínima | La complejidad de sincronización recae entera sobre ti |
Señales de que no necesitas React:
- La página es fundamentalmente contenido con poca o ninguna interacción.
- El SEO y el tiempo de primera carga son críticos y no vas a montar renderizado en servidor.
- El equipo es muy pequeño y la funcionalidad cabe en unos pocos manejadores de eventos.
- Ya existe una solución de servidor (plantillas) que resuelve el problema con menos piezas móviles.
Señales de que sí:
- Hay estado compartido entre varias zonas de la pantalla que debe mantenerse coherente.
- La interfaz se compone de piezas que se repiten con datos distintos (tarjetas, filas, filtros, modales).
- Prevés que la aplicación crecerá y varias personas tocarán el mismo código.
- Necesitas actualizaciones frecuentes sin recargar la página.
- Presentación del proyecto: CicloUrbano
Durante todo el curso construirás CicloUrbano, una aplicación ficticia de alquiler de bicicletas urbanas por estaciones. Cada lección añade una pieza, de modo que al llegar al Módulo 11 tendrás una aplicación completa y no una colección de ejemplos sueltos.
El dominio
// src/datos/dominio.js — la forma de los datos que usaremos en todo el curso
// Bicicleta: { id, modelo, tipo, estado, estacionId, precioHora }
// tipo: 'urbana' | 'electrica' | 'carga'
// estado: 'disponible' | 'alquilada' | 'mantenimiento'
export const bicicletas = [
{ id: 'bici-001', modelo: 'Urbana Clásica', tipo: 'urbana', estado: 'disponible', estacionId: 'est-01', precioHora: 2.5 },
{ id: 'bici-002', modelo: 'Eléctrica Pro', tipo: 'electrica', estado: 'alquilada', estacionId: 'est-01', precioHora: 4.0 },
{ id: 'bici-003', modelo: 'Carga Max', tipo: 'carga', estado: 'mantenimiento', estacionId: 'est-02', precioHora: 5.5 },
{ id: 'bici-004', modelo: 'Urbana Clásica', tipo: 'urbana', estado: 'disponible', estacionId: 'est-03', precioHora: 2.5 },
{ id: 'bici-005', modelo: 'Eléctrica Pro', tipo: 'electrica', estado: 'disponible', estacionId: 'est-02', precioHora: 4.0 }
];
// Estacion: { id, nombre, barrio, plazas }
export const estaciones = [
{ id: 'est-01', nombre: 'Plaza Mayor', barrio: 'Centro', plazas: 20 },
{ id: 'est-02', nombre: 'Parque Norte', barrio: 'Norte', plazas: 15 },
{ id: 'est-03', nombre: 'Estación Central', barrio: 'Ensanche', plazas: 30 }
];
// Usuario: { id, nombre, email, rol } -> rol: 'cliente' | 'operario'
export const usuarios = [
{ id: 'usr-01', nombre: 'Ana Ribera', email: '[email protected]', rol: 'cliente' },
{ id: 'usr-02', nombre: 'Marc Solé', email: '[email protected]', rol: 'operario' }
];
// Reserva: { id, bicicletaId, usuario, fechaInicio, horas, estado }
export const reservas = [
{ id: 'res-01', bicicletaId: 'bici-002', usuario: 'usr-01', fechaInicio: '2026-05-04T09:00', horas: 2, estado: 'activa' }
];Todos los datos son ficticios: nombres, correos y estaciones están inventados para el curso. Nunca uses datos reales de personas al practicar.
Alcance funcional que iremos construyendo
flowchart TD
A[CicloUrbano] --> B[Catálogo de bicicletas<br/>Módulos 1-3]
A --> C[Filtros, búsqueda y formularios<br/>Módulo 3]
A --> D[Estado compartido y hooks<br/>Módulos 4-5]
A --> E[Navegación entre páginas<br/>Módulo 6]
A --> F[Estado global y datos del servidor<br/>Módulo 7]
A --> G[Rendimiento y pruebas<br/>Módulos 8-9]
A --> H[Aplicación completa desplegada<br/>Módulos 10-11]
En términos de producto, CicloUrbano permitirá:
- Consultar el catálogo de bicicletas con su modelo, tipo, estado y precio por hora.
- Filtrar por tipo, estado y estación, y buscar por modelo.
- Ver el detalle de una estación con sus bicicletas y sus plazas libres.
- Crear una reserva mediante un formulario validado.
- Consultar el listado de reservas del usuario y cancelarlas.
- Ofrecer un panel de operario con acceso restringido por rol.
Errores Comunes y Consejos
- Creer que React sustituye a HTML, CSS o JavaScript. No lo hace. Cuanto mejor domines el DOM, la cascada CSS y las promesas, mejor React escribirás. Si algo de ES6+ te falla, refuérzalo ahora: destructuring, spread,
map/filtery funciones flecha aparecen en literalmente todas las lecciones. - Intentar tocar el DOM «a mano» dentro de un componente. Un
document.getElementById(...).innerHTML = ...dentro de React entra en conflicto directo con lo que React cree que hay pintado. Existen vías legítimas para acceder al DOM cuando de verdad hace falta (useRef, lección 05-03), pero son la excepción. - Elegir React por moda. Justifica la decisión: ¿hay estado rico? ¿la interfaz cambia mucho? ¿el equipo va a crecer? Si las tres respuestas son no, quizá no lo necesites.
- Aprender copiando sin escribir. Teclea los ejemplos de este curso en tu propio proyecto. La memoria muscular sobre la sintaxis JSX se construye escribiéndola, no leyéndola.
- Confundir «declarativo» con «automático». React automatiza la actualización del DOM, no el diseño de tu estado. Modelar bien los datos sigue siendo tu trabajo y es la decisión que más impacto tendrá en la calidad del código.
Ejercicios
Ejercicio 1
Identifica, en el fragmento imperativo del apartado 1, las cuatro responsabilidades distintas que asume el programador y que en la versión React desaparecen o las asume la biblioteca. Escríbelas con tus palabras.
Ejercicio 2
Para cada uno de estos cuatro proyectos, decide si usarías React o no y justifica la respuesta en dos o tres líneas:
- La página de aviso legal de CicloUrbano: texto estático, sin interacción.
- Un panel para operarios que muestra el estado de 200 bicicletas y se refresca cada 10 segundos.
- Un formulario de contacto de cuatro campos en una web corporativa hecha con plantillas de servidor.
- La aplicación de cliente de CicloUrbano: catálogo, filtros, reservas y área personal.
Ejercicio 3
Escribe el objeto JavaScript correspondiente a una nueva bicicleta de CicloUrbano que cumpla todas estas condiciones, respetando exactamente la forma del dominio definida en el apartado 8: es del modelo «Carga Max», está disponible, se encuentra en la estación «Estación Central» y cuesta 5,50 € la hora. Después escribe la expresión que, partiendo del array bicicletas, devuelve solo las bicicletas disponibles de la estación est-01.
Soluciones
Solución 1.
- Construir el DOM nodo a nodo: crear cada elemento, asignar clases y textos, y colgarlos del contenedor. En React describes el resultado con JSX y la biblioteca crea los nodos.
- Borrar lo anterior antes de repintar (
innerHTML = ''). React calcula las diferencias y solo modifica lo que ha cambiado, sin destruir el resto. - Decidir cuándo repintar: acordarse de llamar a
pintarCatalogo()tras cada cambio. En React, cambiar el estado dispara el nuevo render automáticamente. - Mantener sincronizados los elementos secundarios (el contador y el texto del botón). En React ambos son expresiones derivadas del estado, así que no pueden quedarse desfasados.
Solución 2.
- No. Contenido estático sin estado: HTML y CSS bastan. Añadir React encarece la carga y el mantenimiento sin aportar nada.
- Sí. Estado abundante, cambiante y compartido entre varias zonas de pantalla: es exactamente el escenario para el que React fue diseñado.
- Probablemente no. Un formulario aislado dentro de una web de servidor se resuelve con JavaScript estándar. Introducir React implicaría un proceso de construcción entero para muy poca ganancia. Si en el futuro hubiera muchos formularios con validación compleja, la decisión podría cambiar.
- Sí. Muchas vistas que comparten datos, navegación entre páginas, interacción constante y un equipo que crecerá: React aporta estructura, reutilización y ecosistema.
Solución 3.
// Nueva bicicleta respetando la forma del dominio
const nuevaBicicleta = {
id: 'bici-006',
modelo: 'Carga Max',
tipo: 'carga',
estado: 'disponible',
estacionId: 'est-03', // 'Estación Central'
precioHora: 5.5
};
// Bicicletas disponibles de la estación est-01 ('Plaza Mayor')
const disponiblesPlazaMayor = bicicletas.filter(
(b) => b.estado === 'disponible' && b.estacionId === 'est-01'
);
// -> [{ id: 'bici-001', modelo: 'Urbana Clásica', ... }]Fíjate en que tipo se deduce del modelo («Carga Max» es de tipo 'carga') y en que la estación se referencia por su id, nunca por su nombre: los identificadores son estables y los nombres podrían cambiar.
Conclusión
React resuelve un problema muy concreto: mantener la interfaz sincronizada con los datos sin que tú tengas que orquestar cada actualización del DOM. Lo consigue con un modelo declarativo («así se ve la pantalla con estos datos») y basado en componentes (piezas con nombre propio que se combinan y reutilizan), resumido en la idea de que la interfaz es una función del estado. Es una biblioteca, no un framework: te da la capa de interfaz y te deja elegir el resto. Encaja cuando hay estado rico e interacción constante, y sobra cuando la página es esencialmente contenido estático.
También conoces ya CicloUrbano, su dominio y los datos de ejemplo que reaparecerán en cada lección del curso.
En la siguiente lección, Configuración del Entorno de Desarrollo, pasarás de la teoría a la práctica: instalarás Node.js, crearás el proyecto de CicloUrbano con Vite, entenderás para qué sirve cada carpeta generada y dejarás el servidor de desarrollo funcionando con recarga en caliente.
Curso de React
Módulo 1: Introducción a React
- ¿Qué es React?
- Configuración del Entorno de Desarrollo
- Hola Mundo en React
- JSX: Extensión de Sintaxis de JavaScript
- Cómo Renderiza React: Virtual DOM y Reconciliación
Módulo 2: Componentes de React
- Entendiendo los Componentes
- Componentes Funcionales vs de Clase
- Props: Pasando Datos a Componentes
- State: Gestión del Estado del Componente
- Estilos en los Componentes: CSS, Módulos y Utilidades
Módulo 3: Trabajando con Eventos
- Manejo de Eventos en React
- Renderizado Condicional
- Listas y Claves
- Formularios y Componentes Controlados
- Validación de Formularios y Componentes No Controlados
- Accesibilidad en Componentes Interactivos
Módulo 4: Conceptos Avanzados de Componentes
- Elevando el Estado
- Composición vs Herencia
- Métodos del Ciclo de Vida de React
- Hooks: Introducción y Uso Básico
- Límites de Error: Capturar Fallos en la Interfaz
Módulo 5: Hooks de React
- Hook useState
- Hook useEffect
- Hook useRef y Acceso al DOM
- Hook useContext
- Hook useReducer
- Hooks Personalizados
Módulo 6: Enrutamiento en React
- Introducción a React Router
- Configuración de React Router
- Rutas Anidadas
- Navegación Programática
- Rutas Protegidas y Control de Acceso
Módulo 7: Gestión del Estado
- Introducción a la Gestión del Estado
- API de Contexto
- Redux: Introducción y Configuración
- Redux: Acciones y Reductores
- Redux: Conectando a React
- Estado del Servidor: Peticiones, Caché y Sincronización
Módulo 8: Optimización del Rendimiento
- Técnicas de Optimización del Rendimiento en React
- Memorización con React.memo
- Hooks useMemo y useCallback
- División de Código y Carga Perezosa
- Medir el Rendimiento con React DevTools Profiler
Módulo 9: Pruebas en React
- Introducción a las Pruebas
- Pruebas Unitarias con Jest
- Pruebas de Componentes con React Testing Library
- Pruebas de Código Asíncrono y Simulación de APIs
- Pruebas de Extremo a Extremo con Cypress
Módulo 10: Temas Avanzados
- Renderizado del Lado del Servidor (SSR) con Next.js
- Generación de Sitios Estáticos (SSG) con Next.js
- Suspense y React Server Components
- TypeScript con React
- React Native: Creación de Aplicaciones Móviles
