Paginación de Cursos con React y TanStack Query

Clase 30 de 31Curso de React Avanzado

Resumen

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: <h1>Learning Courses</h1> 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.