Optimiza tu aplicación de cursos con code splitting en React, cargando componentes solo cuando hacen falta. Aquí verás cómo aplicar React.lazy para un import dinámico, tipar props con TypeScript y controlar estados de carga y error usando un hook personalizado con soporte de TankStack Query. Flujo claro, rendimiento mejorado y una UI predecible.
¿Qué es code splitting y cómo aplicarlo con React.lazy?
El objetivo es cargar el código bajo demanda y no todo de una vez. Para ello se usa React.lazy con un import dinámico del componente de lista de cursos. Así, la UI muestra el componente solo cuando se necesita, reduciendo el paquete inicial.
Code splitting: carga diferida del componente.
Import dinámico: función que resuelve el módulo cuando se requiere.
Ventaja: mejora el tiempo de carga inicial.
// App.tsximportReactfrom'react';importuseCoursesfrom'./hooks/useCourses';constCourseList=React.lazy(()=>import('./components/CourseList'));exportconstApp:React.FC=()=>{const{ data: courses, loading, error }=useCourses();if(loading)return<>cargando</>;if(error)return<>error: {String(error)}</>;if(!courses)return<>no se han encontrado cursos</>;return<CourseListcourses={courses}/>;};
¿Por qué usar import dinámico con lazy?
Evita cargar CourseList antes de tiempo.
Mantiene el código modular y escalable.
Se integra con el estado de carga para evitar pantallas en blanco.
¿Cómo tipar y renderizar CourseList con TypeScript?
Se define una interfaz para los cursos y se crea un functional component que recibe un arreglo tipado. La lista se pinta con ul/li, usando map y una key única por elemento.
Interfaz clara: id, title, description, duration.
Props tipadas: seguridad al acceder a campos.
Key única: evita problemas de render y reconcilación.
Map sin return explícito: usar paréntesis para legibilidad.
Export default: facilita el lazy import.
¿Cómo manejar carga y errores con un hook y TankStack Query?
Se usa un hook personalizado, useCourses, que expone data, un estado de cargando y error. Con retornos tempranos se decide qué mostrar: texto de “cargando”, mensajes de “no se han encontrado cursos” o el detalle del error.
Hook personalizado: encapsula la lógica de datos.
Cargando y error: estados controlados por la librería.
Retornos tempranos: evitan render innecesario.
// App.tsx (fragmento de la lógica de render)if(loading)return<>cargando</>;if(error)return<>error: {String(error)}</>;if(!courses)return<>no se han encontrado cursos</>;return<CourseListcourses={courses}/>;
¿Qué beneficios aporta este patrón?
UX consistente durante la carga.
Mensajes claros ante errores.
Código más legible con condiciones simples.
¿Qué habilidades y conceptos se refuerzan?
Code splitting con React.lazy para mejorar rendimiento.
Import dinámico con función de import en tiempo de ejecución.
TypeScript interfaces para datos de cursos.
Functional component y props tipadas.
Map de arreglos y uso correcto de key.
Manejo de estados de “cargando” y “error”.
Retorno temprano para controlar el flujo de render.
Mensajes en la UI para feedback inmediato.
¿Tienes dudas sobre el lazy import o el manejo de errores? Comparte tus preguntas y cuéntame qué parte te gustaría profundizar.
El code splitting es una técnica en el desarrollo de aplicaciones web que permite dividir el código fuente en partes más pequeñas. Esto se realiza para cargar solo el código necesario en el momento en que se requiere, en lugar de cargar todo de una vez. Así, se mejora el rendimiento y reduce el tiempo de carga inicial. En el contexto de React, esto se aplica a través de funciones como React.lazy() y Suspense, permitiendo la carga dinámica de componentes según la necesidad del usuario.
No sé si se hace en clases más adelante pero en clases anteriores existió el mismo error
Por más que se use lazy loading, no sirve de nada si no se usa un suspense para cargar el componente, idealmente con un fallback que muestra un componente Loader mientras el lazy hace el llamado (eso toma tiempo obviamente porque se está descargando)
Buenas! aunque no utilices el Suspense, la carga diferida si se estaría realizando, lo único que a nivel visual mostraría la vista vacía hasta que este disponible la información. O sea, a nivel visual si que es mejor poner el Suspense para mostrar un estado de carga, pero que no se ponga no quita que la carga diferida deje de funcionar.
Igualmente ella para esto ha utilizado los renderizados condicionales, con los if.
un saludo
Creo que no ha sido bien elegido el ejemplo para una carga diferida. Ya q en este caso la optimización casi ni se notaría, hubiera sido mejor un ejemplo donde el listado hiciera su propia petición, y esta no se ejecute hasta que sea necesario, pero en el ejemplo entiendo que la petición a bbdd que sería lo más costoso, se estaría ejecutando igualmente antes de cargar el componte con lel lazy
constCourseList=lazy(()=>import('./components/CourseList'))```Esta parte del codigo da error: Type'Promise\<typeof import("...")>' is not assignable to type 'Promise<{default:ComponentType\<any>;}>sino se exporta el componente por default.En este caso el CourseList debe tener exportdefault...