En este módulo rehacemos DevJobs como una Single Page Application (SPA) usando React 19 y Vite. La aplicación vanilla del módulo anterior se transforma en un proyecto moderno con componentes funcionales, hooks de React, CSS Modules y un sistema de routing implementado desde cero con un custom hook — sin librerías externas de routing. Este módulo sienta las bases de la arquitectura de componentes que evolucionará en el módulo siguiente.Documentation Index
Fetch the complete documentation index at: https://mintlify.com/midudev/jscamp/llms.txt
Use this file to discover all available pages before exploring further.
Lo que aprenderás
- JSX: sintaxis de plantillas de React y diferencias con HTML (camelCase,
className, etc.). - Componentes funcionales: creación de UI reutilizable encapsulada en funciones de JavaScript.
- Hooks de React:
useState,useEffect,useId,useRefaplicados a casos reales. - Custom hooks: extracción de lógica con estado a hooks propios (
useRouter,useSearchForm). - Routing sin librerías externas: implementación de un router SPA usando
window.history.pushStatey el eventopopstate. - CSS Modules: estilos con scope local a nivel de componente para evitar colisiones de nombres.
Estructura del Proyecto
Custom Router Hook
El hookuseRouter implementa el routing client-side sin dependencias externas. Escucha el evento nativo popstate del navegador para detectar cambios de URL y expone la función navigateTo para navegar de forma programática usando la History API.
Route y Link para construir el sistema de navegación completo:
App.jsx define todas las rutas de la aplicación de forma declarativa:
Componentes Principales
Header
Barra de navegación superior con el logotipo SVG de DevJobs como
<Link> y los enlaces de navegación. Incluye un enlace convencional (<a>) junto a un <Link> SPA para comparar ambos comportamientos.Footer
Pie de página simple con el texto de copyright. Componente stateless de presentación pura.
JobCard
Tarjeta de oferta de empleo. Gestiona el estado de
isApplied con useState: al pulsar “Aplicar” el botón cambia a “Aplicado” y se deshabilita visualmente. Recibe el objeto job como prop.JobListings
Contenedor que recibe un array
jobs y renderiza un <JobCard> por cada elemento. Muestra un mensaje cuando no hay resultados que coincidan con los filtros activos.SearchFormSection
Formulario de búsqueda avanzada con tres selectores (tecnología, ubicación, nivel de experiencia) y un input de texto con debounce de 500 ms. Extrae su lógica al hook interno
useSearchForm.Pagination
Navegación entre páginas de resultados. Genera las URLs con
URLSearchParams para que cada página sea enlazable. Deshabilita los botones anterior/siguiente en los extremos.Route
Componente de routing condicional: compara
currentPath (del hook useRouter) con su prop path y renderiza el componente asociado únicamente cuando coinciden.Link
Versión SPA del elemento
<a>: intercepta el click, llama a navigateTo del hook useRouter y evita la recarga de página mientras mantiene la URL accesible en el href.Scripts disponibles
Los siguientes scripts están definidos enpackage.json:
| Script | Comando | Descripción |
|---|---|---|
dev | vite | Inicia el servidor de desarrollo con HMR en localhost:5173 |
build | vite build | Genera el bundle de producción optimizado en dist/ |
lint | eslint . | Analiza el código con ESLint y las reglas de React Hooks |
preview | vite preview | Sirve el bundle de producción localmente para previsualizar |
Cómo Ejecutar
Si quieres explorar React sin ningún paso de compilación, el repositorio incluye la carpeta
02-react-cdn-version/ donde la misma aplicación se carga desde un CDN usando importmap y JSX compilado en el navegador con Babel Standalone. Es ideal para entender los fundamentos antes de introducir herramientas de build.