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.tsx
import React from 'react';
import useCourses from './hooks/useCourses';
const CourseList = React.lazy(() => import('./components/CourseList'));
export const App: 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 <CourseList courses={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.
// components/CourseList.tsx
import React from 'react';
interface Course {
id: number;
title: string;
description: string;
duration: string;
}
interface Props {
courses: Course[];
}
const CourseList: React.FC<Props> = ({ courses }) => {
return (
<ul>
{courses.map((course) => (
<li key={course.id}>
<h3>{course.title}</h3>
<p>{course.description}</p>
<small>{course.duration}</small>
</li>
))}
</ul>
);
};
export default CourseList;
¿Qué detalles de la UI conviene cuidar?
- Estructura simple: títulos, párrafos y duració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 <CourseList courses={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.