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:

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.