Saltar al contenido principal
Logo FPCode

Librerías y frameworks de cliente: de JavaScript puro a React

Contenido

Unidad puente de Desarrollo web en entorno cliente para comprender por qué se usan librerías y frameworks, qué problemas resuelven, cómo cambia el modelo de trabajo y cómo preparar el salto a React.

Introducción

En las unidades anteriores has trabajado con JavaScript directamente en el navegador: has seleccionado elementos del DOM, escuchado eventos, validado formularios, creado nodos y consumido datos con fetch. Ese conocimiento es imprescindible porque las librerías y frameworks de cliente no sustituyen la base de JavaScript: la organizan y la escalan.

Cuando una página tiene pocas interacciones, JavaScript puro puede ser suficiente. Sin embargo, cuando la interfaz crece, aparecen problemas de organización: muchas funciones modificando el DOM, datos duplicados en distintas partes, formularios que dependen unos de otros, estados de carga y error, listas filtradas, componentes repetidos y dificultad para saber qué parte del código actualiza cada zona de la pantalla.

Las librerías y frameworks de cliente nacen para resolver esos problemas. Esta unidad explica qué aportan, cómo cambia el modelo mental respecto al DOM manual y por qué React será el primer framework que estudiaremos con más profundidad.

Conocimiento previo

  • HTML
  • JavaScript
  • Uso de fetch, JSON y renderizado de datos en el DOM.

Referencias

Índice

  1. El límite práctico del DOM manual
  2. Qué aporta una librería de interfaz
  3. Qué aporta un framework completo
  4. Componente: la unidad de construcción de una interfaz
  5. Estado: los datos que hacen cambiar la pantalla
  6. Renderizado declarativo frente a manipulación manual
  7. Props: datos que viajan entre componentes
  8. Eventos en una interfaz basada en componentes
  9. Listas, claves y repetición de elementos
  10. React como biblioteca para construir interfaces 10.1. JSX no es HTML, aunque se parezca 10.2. React favorece pensar en datos y componentes 10.3. React encaja bien con interfaces que cambian mucho
  11. Angular como framework de aplicación
  12. Vue como enfoque progresivo
  13. Ecosistema moderno: npm, Vite, TypeScript y herramientas
  14. Cuándo usar JavaScript puro y cuándo usar un framework
  15. Criterios para elegir tecnología en un proyecto
  16. Preparación para la unidad de React
  17. Actividad guiada: analizar una interfaz antes de programarla 17.1. Identificar componentes candidatos 17.2. Identificar estado necesario 17.3. Decidir si usar framework
  18. Ejercicios

1. El límite práctico del DOM manual

El DOM manual funciona bien cuando la página tiene pocas zonas dinámicas. Por ejemplo, una lista de tareas pequeña, un formulario con validación sencilla o un botón que muestra y oculta contenido se pueden resolver con querySelector(), addEventListener() y createElement().

El problema aparece cuando la interfaz empieza a crecer. Imagina una página de catálogo con estas funciones:

  • Cargar productos desde una API.
  • Mostrar estados de carga, éxito y error.
  • Filtrar por texto.
  • Filtrar por categoría.
  • Ordenar por precio.
  • Añadir productos a favoritos.
  • Mostrar un contador de resultados.
  • Reutilizar la misma tarjeta de producto en varias páginas.
  • Mantener el formulario sincronizado con la lista.

Con DOM manual, es fácil acabar con muchas funciones actualizando distintas partes de la página. Si cambia el array de productos, quizá tengas que recordar actualizar la lista, el contador, el mensaje de estado y los botones. Si olvidas una zona, la pantalla muestra información incoherente.

Ejemplo de problema típico:

const productos = [];
function añadirProducto(producto) {
productos.push(producto);
renderizarLista();
actualizarContador();
mostrarMensaje('Producto añadido');
}

Este código puede funcionar, pero obliga a recordar manualmente qué partes de la interfaz dependen de productos. A medida que aumenta el número de estados, también aumenta la probabilidad de errores de sincronización.

Una librería como React propone otra forma de pensar: describir cómo debe verse la interfaz para un estado concreto y dejar que la herramienta actualice la pantalla cuando ese estado cambie.

2. Qué aporta una librería de interfaz

Una librería de interfaz se centra en resolver una parte concreta del problema: construir y actualizar la interfaz de usuario. React es el ejemplo principal que trabajaremos.

Una librería no suele imponer toda la arquitectura de la aplicación. Te da herramientas para crear componentes, gestionar estado y renderizar la pantalla, pero normalmente deja que elijas otras piezas: enrutado, consumo de datos, estructura de carpetas o librerías auxiliares.

Una librería de interfaz aporta:

NecesidadQué aporta la librería
Reutilizar partes visualesComponentes.
Actualizar la pantalla al cambiar datosRenderizado declarativo.
Evitar manipulación DOM repetitivaPlantillas o JSX.
Separar responsabilidadesComponentes pequeños con propósito claro.
Mantener datos de interfazEstado.
Pasar datos entre partesProps o mecanismos equivalentes.

La idea importante es que no se abandona JavaScript. Se escribe JavaScript con una forma de organización más adecuada para interfaces grandes.

3. Qué aporta un framework completo

Un framework completo ofrece una solución más cerrada y guiada. Angular es el ejemplo principal dentro del desarrollo cliente moderno.

Un framework suele incluir o definir más piezas:

  • Sistema de componentes.
  • Plantillas.
  • Enrutado.
  • Formularios.
  • Comunicación HTTP.
  • Inyección de dependencias.
  • Herramientas de línea de comandos.
  • Estructura de proyecto recomendada.
  • Convenciones de arquitectura.

Esto tiene ventajas y costes. La ventaja es que el equipo dispone de una forma común de construir aplicaciones. El coste es que hay más conceptos que aprender desde el principio y menos libertad para mezclar enfoques.

Comparación general:

EnfoqueVentaja principalCoste principal
JavaScript puroControl directo y poca configuración.Difícil de escalar si la interfaz crece.
Librería de interfazFlexibilidad y componentes reutilizables.Hay que elegir otras piezas del ecosistema.
Framework completoConvenciones y solución integrada.Curva de aprendizaje más alta.

No existe una opción universalmente mejor. La decisión depende del tipo de proyecto, el equipo, el mantenimiento previsto y la complejidad de la interfaz.

4. Componente: la unidad de construcción de una interfaz

Un componente es una parte de la interfaz con estructura, datos y comportamiento relacionados. Puede ser pequeño, como un botón, o más amplio, como un formulario de búsqueda.

Ejemplos de componentes:

  • BotonPrincipal
  • CampoBusqueda
  • TarjetaProducto
  • ListaProductos
  • FormularioRegistro
  • MensajeEstado

La clave es que un componente debe tener una responsabilidad comprensible. Si un componente hace demasiadas cosas, se vuelve difícil de reutilizar y probar.

Ejemplo conceptual de una interfaz dividida en componentes:

CatalogoProductos
├─ BuscadorProductos
├─ FiltrosCategoria
├─ ResumenResultados
└─ ListaProductos
├─ TarjetaProducto
├─ TarjetaProducto
└─ TarjetaProducto

En JavaScript puro, podrías crear funciones para generar cada parte del DOM. En React, esas partes se expresan como componentes que devuelven JSX.

Ejemplo simplificado en React:

function TarjetaProducto({ producto }) {
return (
<article className="producto">
<h2>{producto.nombre}</h2>
<p>{producto.precio}</p>
</article>
);
}

Este ejemplo todavía no pretende que domines React. Lo importante es observar el cambio: la estructura visual se describe dentro de una función, usando datos recibidos desde fuera.

5. Estado: los datos que hacen cambiar la pantalla

El estado es la información que puede cambiar durante la ejecución y que afecta a lo que se muestra.

Ejemplos de estado:

  • Texto escrito en un buscador.
  • Producto seleccionado.
  • Lista de tareas.
  • Usuario autenticado.
  • Resultado de una petición HTTP.
  • Mensaje de error.
  • Indicador de carga.

En DOM manual, tú decides cuándo actualizar cada elemento. En React, un cambio de estado provoca que React vuelva a calcular qué debe mostrarse.

Ejemplo conceptual con DOM manual:

let contador = 0;
boton.addEventListener('click', () => {
contador += 1;
salida.textContent = contador;
});

Ejemplo conceptual en React:

import { useState } from 'react';
function Contador() {
const [contador, setContador] = useState(0);
return (
<button onClick={() => setContador(contador + 1)}>
Clics: {contador}
</button>
);
}

En ambos casos hay un dato que cambia. La diferencia es que React relaciona de forma más directa el dato contador con la interfaz que depende de él.

6. Renderizado declarativo frente a manipulación manual

En el enfoque imperativo, explicas paso a paso cómo cambiar la pantalla.

mensaje.textContent = 'Cargando...';
lista.replaceChildren();
boton.disabled = true;

Este estilo es directo y útil, pero puede complicarse si muchos elementos dependen de los mismos datos.

En el enfoque declarativo, describes qué debe mostrarse para cada estado.

Ejemplo conceptual:

function EstadoCarga({ cargando, error }) {
if (cargando) {
return <p>Cargando datos...</p>;
}
if (error) {
return <p>No se han podido cargar los datos.</p>;
}
return <p>Datos disponibles.</p>;
}

No se indica qué nodo hay que borrar, cuál hay que crear o qué texto concreto hay que sustituir. Se expresa el resultado esperado. La librería se encarga de actualizar la interfaz.

Este cambio de mentalidad es una de las razones por las que React resulta útil en interfaces con muchos estados.

7. Props: datos que viajan entre componentes

Las props son datos que un componente recibe desde su componente padre. Permiten reutilizar la misma estructura con información distinta.

Ejemplo:

function Saludo({ nombre }) {
return <p>Hola, {nombre}</p>;
}
function App() {
return (
<section>
<Saludo nombre="Ana" />
<Saludo nombre="Luis" />
</section>
);
}

El componente Saludo no decide por sí mismo el nombre. Lo recibe mediante props. Esto lo hace reutilizable.

En una aplicación de catálogo, una tarjeta de producto podría recibir un objeto producto:

function TarjetaProducto({ producto }) {
return (
<article>
<h2>{producto.nombre}</h2>
<p>{producto.precio}</p>
</article>
);
}

Las props ayudan a mantener una dirección clara de datos: un componente superior calcula o recibe la información, y los componentes inferiores la muestran.

8. Eventos en una interfaz basada en componentes

En DOM manual registras eventos sobre elementos seleccionados:

boton.addEventListener('click', () => {
console.log('Clic');
});

En React, los eventos se escriben dentro del JSX mediante propiedades como onClick, onChange o onSubmit.

function BotonSaludo() {
function saludar() {
console.log('Hola');
}
return <button onClick={saludar}>Saludar</button>;
}

La lógica sigue siendo JavaScript, pero se coloca junto a la descripción del elemento que dispara el evento.

Ejemplo con formulario:

function FormularioBusqueda() {
function manejarEnvio(event) {
event.preventDefault();
console.log('Buscar');
}
return (
<form onSubmit={manejarEnvio}>
<input name="busqueda" type="search" />
<button type="submit">Buscar</button>
</form>
);
}

El patrón es parecido al que ya conoces: prevenir envío, leer datos y ejecutar una acción. La diferencia es la forma de organizarlo dentro del componente.

9. Listas, claves y repetición de elementos

En JavaScript puro, renderizabas listas con forEach(), createElement() y append().

productos.forEach((producto) => {
const item = document.createElement('li');
item.textContent = producto.nombre;
lista.append(item);
});

En React, se usa normalmente map() para transformar datos en elementos JSX.

function ListaProductos({ productos }) {
return (
<ul>
{productos.map((producto) => (
<li key={producto.id}>{producto.nombre}</li>
))}
</ul>
);
}

La propiedad key ayuda a React a identificar cada elemento de la lista cuando hay cambios. Debe ser estable y única dentro de esa lista. Un identificador de base de datos o un id propio suele ser mejor que usar la posición del array.

Este patrón aparecerá constantemente en React:

  1. Tener un array de datos.
  2. Transformarlo con map().
  3. Devolver un componente o elemento por cada dato.
  4. Añadir una key estable.

10. React como biblioteca para construir interfaces

React es una biblioteca de JavaScript para construir interfaces de usuario mediante componentes. Su objetivo principal es facilitar la creación de interfaces que cambian con el tiempo sin tener que manipular manualmente cada nodo del DOM.

React se apoya en varios conceptos:

ConceptoSignificado inicial
ComponenteFunción que describe una parte de la interfaz.
JSXSintaxis que permite describir estructura de interfaz dentro de JavaScript.
PropsDatos que recibe un componente.
EstadoDatos internos que pueden cambiar y provocar nuevo renderizado.
Renderizado declarativoDescripción de cómo debe verse la interfaz según los datos.
HooksFunciones especiales para usar características de React, como estado.

React no obliga a construir toda la aplicación de una única manera. Por eso se suele combinar con herramientas como Vite, frameworks basados en React, librerías de rutas o soluciones de obtención de datos según el proyecto.

10.1. JSX no es HTML, aunque se parezca

JSX permite escribir una estructura parecida a HTML dentro de JavaScript.

function Titulo() {
return <h1>Catálogo de productos</h1>;
}

Aunque se parece a HTML, JSX tiene reglas propias:

  • Se usa className en lugar de class.
  • Las expresiones JavaScript se escriben entre llaves.
  • Un componente debe devolver una única estructura raíz o un fragmento.
  • Las etiquetas deben estar correctamente cerradas.

Ejemplo con expresión:

function Precio({ valor }) {
return <p>Precio: {valor.toFixed(2)}</p>;
}

10.2. React favorece pensar en datos y componentes

En una aplicación React no se empieza seleccionando elementos con querySelector(). Se empieza pensando en datos y componentes.

Preguntas útiles:

  • ¿Qué datos necesita esta pantalla?
  • ¿Qué partes visuales se repiten?
  • ¿Qué componentes pueden extraerse?
  • ¿Qué datos cambian con la interacción?
  • ¿Qué componente debe guardar ese estado?
  • ¿Qué componentes solo reciben datos y los muestran?

Este análisis previo evita crear componentes demasiado grandes o estados duplicados.

10.3. React encaja bien con interfaces que cambian mucho

React suele ser una buena opción cuando la interfaz tiene:

  • Muchas piezas reutilizables.
  • Estado compartido entre partes de la pantalla.
  • Listas dinámicas.
  • Formularios interactivos.
  • Filtros y búsquedas en tiempo real.
  • Vistas que dependen de datos remotos.
  • Necesidad de mantener una estructura de componentes a largo plazo.

No es necesario usar React para cualquier página. Una página informativa con poca interacción puede resolverse mejor con HTML, CSS y algo de JavaScript puntual.

11. Angular como framework de aplicación

Angular es un framework completo para construir aplicaciones cliente, especialmente usado en proyectos empresariales y equipos que valoran una arquitectura integrada.

Angular suele trabajar con:

  • Componentes.
  • Plantillas.
  • TypeScript como lenguaje principal.
  • Servicios e inyección de dependencias.
  • Routing integrado.
  • Formularios de plantilla y formularios reactivos.
  • Cliente HTTP.
  • Herramientas oficiales de generación y construcción.

La diferencia principal respecto a React no es que uno sea “mejor” que otro, sino el nivel de estructura que aporta desde el inicio.

Angular puede ser adecuado cuando:

  • El proyecto es grande y necesita convenciones fuertes.
  • El equipo quiere una solución integrada.
  • Se trabaja con TypeScript de forma intensiva.
  • Hay formularios complejos, rutas, servicios y módulos bien definidos.
  • Se valora que muchas decisiones estén guiadas por el framework.

Como contrapartida, la curva de aprendizaje inicial suele ser mayor. Hay más conceptos que dominar antes de sentirse productivo.

12. Vue como enfoque progresivo

Vue es un framework progresivo para construir interfaces. Se suele presentar como una opción flexible que puede incorporarse de forma gradual o usarse para aplicaciones completas.

Vue comparte ideas con React y Angular:

  • Componentes.
  • Estado.
  • Plantillas declarativas.
  • Eventos.
  • Listas y condicionales.
  • Ecosistema de herramientas.

Su sintaxis de plantillas resulta cercana a HTML, lo que puede facilitar la entrada a estudiantes o equipos que vienen de páginas tradicionales.

Vue puede encajar cuando se busca:

  • Buena curva de aprendizaje inicial.
  • Componentes reutilizables.
  • Flexibilidad para crecer progresivamente.
  • Separación clara entre plantilla, lógica y estilos en componentes de archivo único.

En este itinerario no profundizaremos en Vue, pero conocer su posición ayuda a comparar tecnologías de forma razonada.

13. Ecosistema moderno: npm, Vite, TypeScript y herramientas

Trabajar con frameworks modernos implica usar un ecosistema de herramientas. No basta con abrir un archivo HTML en el navegador.

Herramientas habituales:

HerramientaPapel en el proyecto
Node.jsEntorno para ejecutar herramientas de desarrollo.
npmGestor de paquetes y scripts.
ViteHerramienta de desarrollo y construcción para proyectos frontend.
TypeScriptJavaScript con tipos estáticos opcionales.
ESLintDetección de problemas y reglas de calidad.
FormateadorEstilo automático del código.
DevToolsInspección y depuración en navegador.

En proyectos React actuales, una forma habitual de empezar en entorno educativo es usar Vite, porque ofrece servidor de desarrollo rápido y configuración sencilla.

Ejemplo conceptual de flujo con npm:

Terminal window
npm create vite@latest
npm install
npm run dev

No memorices comandos sin entenderlos. Lo importante es saber qué papel tiene cada herramienta:

  • Crear estructura inicial.
  • Instalar dependencias.
  • Levantar servidor de desarrollo.
  • Generar versión de producción.

TypeScript aparece con frecuencia en proyectos React, Angular y Vue porque ayuda a detectar errores antes de ejecutar. Ya tienes una base de JavaScript; TypeScript añade una capa de tipos que puede mejorar mantenimiento y autocompletado en proyectos medianos o grandes.

14. Cuándo usar JavaScript puro y cuándo usar un framework

Usar un framework no siempre mejora un proyecto. También añade dependencias, herramientas, configuración y conceptos nuevos.

JavaScript puro suele ser suficiente cuando:

  • La página tiene pocas interacciones.
  • El comportamiento es puntual y fácil de aislar.
  • No hay muchas zonas que dependan del mismo estado.
  • No necesitas reutilizar componentes complejos.
  • El coste de configurar un proyecto moderno no compensa.

Un framework o librería puede compensar cuando:

  • Hay muchas vistas o pantallas.
  • La interfaz depende de datos que cambian constantemente.
  • Se repiten estructuras visuales.
  • Hay formularios, filtros, carga de datos y estados de error.
  • Varias personas trabajarán sobre el mismo código durante tiempo.
  • Es importante mantener una arquitectura común.

La decisión no debe basarse en moda. Debe basarse en complejidad, mantenimiento y necesidades reales.

15. Criterios para elegir tecnología en un proyecto

Para elegir tecnología conviene evaluar criterios concretos.

CriterioPregunta práctica
Complejidad de interfaz¿Cuántos estados, formularios, listas y vistas habrá?
Tamaño del equipo¿Cuántas personas tocarán el código?
Experiencia previa¿Qué conoce ya el equipo?
Mantenimiento¿El proyecto vivirá semanas, meses o años?
Ecosistema¿Necesitamos rutas, formularios complejos, datos remotos o SSR?
Rendimiento¿La interfaz manipula muchos datos o muchas actualizaciones?
Accesibilidad¿El framework facilita o dificulta mantener interacciones accesibles?
Curva de aprendizaje¿El tiempo de formación compensa el beneficio?

Ejemplos de decisiones razonadas:

SituaciónDecisión probable
Landing page con un menú y un formulario simpleHTML, CSS y JavaScript puntual.
Panel con filtros, tablas y datos remotosReact, Angular o Vue pueden aportar estructura.
Aplicación empresarial con rutas, roles, formularios y serviciosAngular puede encajar por su arquitectura integrada.
Interfaz de producto con muchos componentes reutilizablesReact puede encajar por composición y ecosistema.
Mejora progresiva de una página existenteJavaScript puro o Vue/React incorporado de forma limitada, según contexto.

Una buena elección técnica se puede explicar. Si la única razón es “porque se usa mucho”, falta análisis.

16. Preparación para la unidad de React

La siguiente unidad se centrará en React desde cero. Para entrar con buen pie debes tener claros estos cambios de mentalidad:

En DOM manualEn React
Seleccionas elementos con querySelector().Defines componentes.
Cambias texto con textContent.Renderizas JSX a partir de datos.
Añades nodos con createElement().Transformas arrays en componentes con map().
Registras eventos con addEventListener().Usas props de evento como onClick u onSubmit.
Actualizas manualmente cada zona.Cambias estado y React recalcula la interfaz.
La estructura puede dispersarse en varias funciones.La interfaz se divide en componentes relacionados.

Conceptos que debes repasar antes de empezar React:

  • Funciones y funciones flecha.
  • Desestructuración de objetos.
  • Arrays y map().
  • Objetos como estructuras de datos.
  • Eventos de formularios.
  • preventDefault().
  • fetch, estados de carga y JSON.
  • Separación entre datos y renderizado.

Mini ejemplo de transición mental:

const productos = [
{ id: 1, nombre: 'Teclado' },
{ id: 2, nombre: 'Ratón' },
];

Con DOM manual, recorres el array y creas nodos. Con React, transformas el array en elementos JSX:

function ListaProductos({ productos }) {
return (
<ul>
{productos.map((producto) => (
<li key={producto.id}>{producto.nombre}</li>
))}
</ul>
);
}

El dato es el mismo. Cambia la forma de describir la interfaz.

17. Actividad guiada: analizar una interfaz antes de programarla

Antes de elegir React, Angular, Vue o JavaScript puro, analiza la interfaz.

Supón una pantalla de biblioteca con:

  • Buscador por título.
  • Filtro por categoría.
  • Lista de libros.
  • Botón para marcar favoritos.
  • Contador de resultados.
  • Mensaje si no hay resultados.
  • Carga inicial desde API.

17.1. Identificar componentes candidatos

Una posible división sería:

BibliotecaApp
├─ BarraBusqueda
├─ FiltroCategorias
├─ ResumenResultados
├─ ListaLibros
│ └─ TarjetaLibro
└─ MensajeEstado

Cada bloque tiene una responsabilidad clara. Si la lista cambia, ListaLibros y ResumenResultados dependerán de los mismos datos filtrados.

17.2. Identificar estado necesario

Estado probable:

EstadoTipoPara qué sirve
librosArrayDatos recibidos desde API.
busquedaStringTexto escrito por el usuario.
categoriaStringCategoría seleccionada.
favoritosArray o SetLibros marcados como favoritos.
cargandoBooleanMostrar estado de carga.
errorString o nullMostrar problema de carga.

17.3. Decidir si usar framework

Esta interfaz tiene varios estados conectados: datos remotos, filtros, favoritos, contador y mensajes. Se podría hacer con DOM manual, pero un enfoque por componentes probablemente será más mantenible.

La decisión razonada sería: usar React si el proyecto va a crecer, si se reutilizarán componentes y si el equipo está preparado para asumir el ecosistema. Usar JavaScript puro si es una práctica pequeña y el objetivo principal es reforzar DOM y eventos.

18. Ejercicios

Ejercicio 1: Detectar complejidad de interfaz

Elige una página web que uses habitualmente. Identifica al menos cinco zonas dinámicas y explica si se podrían resolver fácilmente con JavaScript puro o si convendría usar componentes.

Ejercicio 2: Dividir una interfaz en componentes

Diseña la estructura de componentes de una pantalla de tienda online con buscador, filtros, listado de productos, carrito y resumen de compra. Representa la jerarquía en forma de árbol.

Ejercicio 3: Diferenciar estado y props

Para una aplicación de tareas, indica qué datos serían estado y qué datos podrían viajar como props a componentes hijos como ListaTareas, TareaItem o ContadorTareas.

Ejercicio 4: Comparar DOM manual y React

Explica cómo renderizarías una lista de productos con DOM manual y cómo cambiaría el enfoque usando React. No hace falta crear un proyecto React; céntrate en la diferencia de mentalidad.

Ejercicio 5: Decidir tecnología

Analiza tres proyectos: una landing page, un panel de administración y una aplicación de reservas. Para cada uno, decide si usarías JavaScript puro, React, Angular o Vue, justificando la decisión.

Ejercicio 6: Preparación para React

Repasa map(), desestructuración y funciones flecha creando un array de productos y transformándolo en un array de textos con el formato Nombre - precio €.

Ejercicio 7: Investigar el ecosistema

Busca qué papel cumplen Node.js, npm y Vite en un proyecto React. Resume cada herramienta en una frase y explica por qué no forman parte del código que se ejecuta directamente en el navegador.

Ejercicio 8: Actividad de arquitectura

Toma el caso de la biblioteca de la actividad guiada y añade dos nuevas funcionalidades. Revisa si la división de componentes y el estado propuesto siguen siendo adecuados o necesitan cambios.