Cuando trabajamos con React y necesitamos consumir datos desde un servidor o un archivo JSON, existen múltiples alternativas como Fetch API, Axios o Custom Hooks. Sin embargo, TanStack Query se ha consolidado como una de las herramientas más potentes para gestionar peticiones asíncronas, caché de datos y comunicación con servidor de forma eficiente. A continuación se explica paso a paso cómo configurar un proyecto desde cero y crear un hook personalizado para consumir una API de cursos.
¿Qué es TanStack Query y por qué cambió de nombre?
TanStack Query es la evolución de lo que anteriormente se conocía como React Query [0:00]. El cambio de nombre responde a que la librería ya no está limitada a React: ahora es compatible con Vanilla JavaScript, TypeScript, Vue, Svelte y otros frameworks. Esta versatilidad la convierte en una opción flexible para cualquier proyecto frontend que necesite manejar el consumo de APIs.
El objetivo principal de TanStack Query es simplificar las peticiones al servidor, gestionar estados de carga y error, y almacenar datos en caché para evitar llamadas innecesarias.
¿Cómo crear el proyecto y configurar TanStack Query?
El primer paso es inicializar un proyecto con Vite y React usando TypeScript [1:10]:
- Ejecutar
npm create vite@latest y seleccionar React con TypeScript.
- Instalar las dependencias con
npm install.
- Instalar TanStack Query desde la documentación oficial con el comando correspondiente de npm.
- Iniciar el servidor de desarrollo con
npm run dev.
Una vez listo el proyecto, se organiza la estructura de carpetas dentro de src:
- components: donde vivirá el componente
CourseList.tsx.
- hooks: donde se creará el custom hook
useCourses.
Para simular una API, se crea un archivo JSON en la carpeta public/api/courses.json [2:24]. Este archivo contiene un array de objetos, cada uno con cuatro propiedades: id (numérico), title (string), description (string) y duration (string). Puedes extenderlo con imágenes u otra información según tus necesidades.
¿Cómo construir el hook useCourses con useQuery?
El corazón de la integración con TanStack Query está en el hook personalizado. Dentro del archivo useCourses, se importan dos elementos fundamentales de la librería: useQuery y QueryFunction [3:46].
¿Cómo definir la interfaz y la función de fetch?
Como el proyecto usa TypeScript, se define primero una interfaz llamada Course que refleja la estructura del JSON [4:06]:
typescript
interface Course {
id: number;
title: string;
description: string;
duration: string;
}
Luego se crea la función fetchCourses, tipada como QueryFunction<Course[]>, lo que indica que resolverá una promesa que devuelve un array de cursos [4:30]. Al ser una petición asíncrona, se utiliza async/await:
typescript
const fetchCourses: QueryFunction<Course[]> = async () => {
const response = await fetch('api/courses.json');
if (!response.ok) {
throw new Error('Network response was not OK');
}
return response.json();
};
El patrón es directo: se realiza el fetch, se verifica que la respuesta sea exitosa con response.ok y, en caso contrario, se lanza un error para que TanStack Query lo gestione automáticamente.
¿Cómo exportar el hook para usarlo en componentes?
Finalmente se crea y exporta el custom hook useCourses [5:50]:
typescript
export const useCourses = () => {
return useQuery<Course[], Error>({
queryKey: ['courses'],
queryFn: fetchCourses,
});
};
Dentro de useQuery se pasan dos propiedades esenciales:
- queryKey: un identificador único (
['courses']) que TanStack Query usa para almacenar los datos en caché [6:30]. Gracias a esta key, si el componente se vuelve a montar o se accede a los mismos datos, la librería evita un refetch innecesario y sirve la información directamente desde la caché.
- queryFn: la función que ejecuta la petición y resuelve la promesa con los datos.
Este hook está listo para ser consumido desde CourseList.tsx, donde se podrán extraer los datos, el estado de carga y los posibles errores de forma declarativa, sin necesidad de manejar useEffect ni useState manualmente.
¿Ya has probado TanStack Query en tus proyectos o sigues usando Fetch API directamente? Comparte tu experiencia y cuéntanos qué enfoque prefieres para el consumo de APIs en React.