Domina una paginación fluida en React con un enfoque práctico y eficiente. Aquí verás cómo calcular y renderizar solo los cursos necesarios por página usando memoization, cómo evitar renders innecesarios con useMemo y cómo integrar Tank Stack Query con Suspense y React.memo para una carga controlada y confiable.
¿Cómo optimizar el render con memoization y useMemo?
Para pintar la lista de cursos por página, se crea una variable derivada llamada currentCourses con useMemo. Así, solo se recalcula cuando cambian sus dependencias y se evita un rerender costoso.
- Definir currentCourses con useMemo y retornar un slice del array original.
- Usar dependencias: cursos, página actual y cursos por página.
- Manejar el caso sin datos: retornar un array vacío.
¿Qué dependencias necesita useMemo?
- courses: fuente de datos a paginar.
- currentPage: página actual seleccionada.
- coursesPerPage: cantidad de cursos por página.
¿Cómo se implementa currentCourses?
const currentCourses = useMemo(() => {
if (!courses?.length) return [];
const indexOfLast = currentPage * coursesPerPage;
const indexOfFirst = indexOfLast - coursesPerPage;
return courses.slice(indexOfFirst, indexOfLast);
}, [courses, currentPage, coursesPerPage]);
¿Cómo calcular índices y usar slice para paginar correctamente?
La lógica clave es obtener el índice del último elemento y restarle la cantidad de cursos por página para hallar el índice del primero. Con eso, slice corta el segmento exacto a renderizar.
- indexOfLast = currentPage × coursesPerPage.
- indexOfFirst = indexOfLast − coursesPerPage.
- Usar courses.slice(indexOfFirst, indexOfLast) para obtener currentCourses.
¿Cómo detectar y corregir errores de índices?
Durante el debugging, un console.log reveló índices invertidos: primero 2 y segundo 0, impidiendo ver cursos. Se corrigieron los nombres y el orden: indexOfLast y indexOfFirst.
console.log('courses', courses);
console.log({ indexOfFirst, indexOfLast });
Datos importantes del escenario:
- array de cursos con 6 elementos.
- Paginación de 2 cursos por página.
- Evitar errores retornando [] si no hay cursos.
¿Cómo integrar Tank Stack Query, Suspense y React.memo en el main?
El main necesita un QueryClientProvider para que la app consuma la API. Se crea un QueryClient, se envuelve la aplicación y se usa Suspense con un fallback que muestra "Loading courses" mientras llega la información. Además, React.memo ayuda a memorizar el componente y prevenir renders innecesarios.
- Envolver la app con provider y pasar la prop client.
- Usar Suspense con fallback para el estado de carga.
- Memorizar el componente de lista con React.memo.
¿Cuál es el esqueleto del main con provider y Suspense?
import React, { Suspense } from 'react';
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
const queryClient = new QueryClient();
<QueryClientProvider client={queryClient}>
<Suspense fallback={<div>Loading courses</div>}>
<CourseList />
</Suspense>
</QueryClientProvider>
¿Cómo se aplica React.memo al listado?
const CourseList = (props) => {
// ... lógica de render y paginación
};
export default React.memo(CourseList);
Extras prácticos mencionados:
- Título visual:
Learning Courses
para mejorar la
UI.
- Ajustes de estilos en index.css.
- Uso de
useTransition y
code splitting para transiciones fluidas.
Claves que te llevas:
- memoization para evitar cálculos y renders innecesarios.
- useMemo con dependencias correctas para paginación.
- slice para cortar rangos de cursos.
- QueryClientProvider y QueryClient para el consumo de datos.
- Suspense con fallback para manejar loading.
- React.memo para componentes más ligeros.
¿Tienes dudas sobre los índices, el fallback o la configuración del provider? Comenta tus preguntas o comparte cómo estructuraste tu paginación en React.