
TanStack Query, antes conocido como React Query, nació en 2019 para simplificar el manejo del estado asíncrono en aplicaciones React. Antes, los desarrolladores usaban combinaciones de useState, useEffect y fetch/axios, generando código repetitivo y difícil de mantener. La librería se adoptó rápidamente porque resolvía problemas comunes:
- Almacenamiento en caché
- Sincronización automática y en segundo plano
- Control del estado de carga y error.
En poco tiempo se consolidó como una de las herramientas más utilizadas para gestionar datos de servidor, superando alternativas más complejas como Redux para datos asíncronos. Gracias a su claridad, comunidad activa y a que actualmente cuenta con 46.8k estrellas en GitHub, hoy es la referencia para manejar datos remotos en aplicaciones modernas con React y Next.js.
Al momento de redactar este artículo, la librería se encuentra en fase experimental. Esto implica que pueden producirse cambios incompatibles incluso en actualizaciones menores o de parche. Se recomienda usarla con precaución y fijar la versión al utilizarla en entornos de producción. Para más detalles y actualizaciones, consulta la documentación oficial.
Configuración inicial

El provider provideTanStackQuery(...) es el encargado de inicializar un QueryClient de TanStack Query y exponerlo dentro del contexto de Angular. Además, se habilita withDevtools(), fundamental porque es lo que permite que la extensión de TanStack Devtools detecte el cliente y muestre en tiempo real el estado de las queries, mutations y el caché de datos de la aplicación.

TanStack Devtools te da control total sobre cuándo y cómo usar las Devtools de TanStack Query en tu app Angular. Más documentación aquí.
- Se incluyen solo en modo desarrollo por defecto.
- Se pueden habilitar en producción importando desde el sub-path
/production. - Soporta carga condicional o perezosa con la opción
loadDevtools(auto,true,false). - Las opciones son reactivas y permiten configurar: posición del panel, si inicia abierto, posición del botón, cliente personalizado, tipos de error, estilos con nonce, Shadow DOM y ocultar queries deshabilitadas.
Conceptos esenciales
Entre las muchas propiedades de configuración que se pueden pasar a la función para manejar datos remotos de forma eficiente, destacan las siguientes:
queryKey: identificador único de cada consulta (clave para el caché).queryFn: función que obtiene los datos (promesa olastValueFromsi usas RxJS).staleTimeycacheTime: diferencia entre “datos frescos” y “datos en caché”.enabled: para ejecutar queries condicionalmente.refetchOnWindowFocusyrefetchInterval: control de actualizaciones automáticas.useQueries: ejecución paralela de múltiples queries (como en tu ejemplo de detalle de película).
Caso práctico 1: Landing page con carrusel de películas
El primer escenario es la landing page con un carrusel de películas. Aquí queremos que, una vez cargadas las películas, permanezcan en caché para que cuando el usuario regrese a la página (desde una página de detalles) no se realice otra solicitud innecesaria. Esto lo logramos configurando un staleTime que defina el tiempo durante el cual los datos se consideran frescos.
De esta manera, el carrusel siempre mostrará las películas de forma instantánea si ya han sido cargadas previamente, evitando llamadas adicionales al servidor y mejorando la percepción de velocidad de la aplicación.

¿Qué es queryKey y cómo funciona?
El queryKey es uno de los conceptos más importantes en TanStack Query. Básicamente, es el identificador único de cada consulta en TanStack Query. Funciona como la “huella digital” de los datos, permitiendo que la librería:
- Use caché: si ya existen datos para esa clave, los muestra al instante.
- Detecte cambios: si la clave cambia, se ejecuta una nueva consulta.
- Organice múltiples queries: cada conjunto de datos tiene su propia clave, incluso si proviene del mismo endpoint.
Ejemplos
- Simple:
queryKey: ['movies'] - Dinámico por ID:
queryKey: ['movie', <movieId>](Cada película tiene su propio caché) - Con parámetros adicionales:
queryKey: ['reviews', { movieId: 1234, language: 'es' }]
Caso práctico 2: Vista de detalles de una película
El segundo escenario ocurre cuando el usuario hace clic en una película para ver sus detalles. En este caso también queremos caché, pero además necesitamos obtener información de distintas fuentes: detalles, reseñas, tráileres oficiales en YouTube, películas similares y recomendaciones personalizadas. Para lograrlo, podemos aprovechar useQueries, que nos permite ejecutar varias peticiones en paralelo y tener los resultados disponibles casi al mismo tiempo.
Así, el detalle de la película se carga rápidamente, mostrando los datos almacenados en caché cuando están disponibles y actualizando de fondo solo lo necesario. Esto da como resultado una experiencia fluida, incluso si el usuario navega de un detalle a otro en poco tiempo.

Caso práctico 3: Reseñas con actualización automática
En este escenario, la sección de reseñas de cada película es muy activa: los usuarios publican comentarios constantemente y queremos que la vista se mantenga actualizada.
Para lograrlo, aprovechamos la capacidad de TanStack Query de refrescar datos automáticamente en segundo plano mediante la propiedad refetchInterval. Esto permite ejecutar nuevamente la consulta (queryFn) en intervalos regulares, manteniendo los datos sincronizados sin interrumpir la experiencia del usuario.
query = injectQueries(() => ({
queryKey: ['movie-details', this.id()],
queries: [
{ queryKey: ['movie', this.id()], queryFn: this.fetchMovie },
{
queryKey: ['reviews', this.id()],
queryFn: this.fetchReviews,
refetchInterval: 5 * 60 * 1000, // actualiza cada 5 minutos
refetchOnWindowFocus: true, // también al volver a la pestaña
staleTime: 2 * 60 * 1000, // los datos se consideran frescos durante 2 minutos
},
{ queryKey: ['videos', this.id()], queryFn: this.fetchVideos },
{ queryKey: ['similar', this.id()], queryFn: this.fetchSimilar },
{ queryKey: ['recommendations', this.id()], queryFn: this.fetchRecommendations },
],
}));
Con esta configuración:
- Las reseñas se actualizan automáticamente cada 5 minutos;
- Si el usuario cambia de pestaña TanStack Query detiene las actualizaciones;
- Si el usuario regresa, el sistema detecta el enfoque de la ventana y vuelve a sincronizar los datos automáticamente;
- Gracias al caché interno, la lista se muestra al instante y solo se recarga lo necesario, sin afectar el rendimiento ni mostrar pantallas de carga innecesarias.
Caso práctico 4: Precarga de datos al pasar el cursor sobre una película
En este escenario queremos mejorar aún más la percepción de velocidad de la aplicación. Cuando el usuario navega por el carrusel o lista de películas, cada vez que pasa el cursor sobre botón "detalle", anticipamos que podría abrir la vista de detalles.
Para que esa página cargue instantáneamente, podemos usar prefetching con TanStack Query, es decir, precargar los datos de una película antes de que el usuario haga clic.
TanStack Query expone esta funcionalidad a través del QueryClient, que permite ejecutar la queryFn y guardar el resultado en caché sin renderizar aún ningún componente.
Beneficios del prefetching

- Cero tiempo de carga percibido: cuando el usuario finalmente hace clic en la película, los datos ya están en caché.
- Eficiencia: si el usuario no llega a abrir el detalle, TanStack descarta el caché después de
cacheTimesin afectar el rendimiento. - Combinable: puedes precargar también las queries de videos, reseñas o recomendaciones si quieres una transición totalmente instantánea.
Conclusión
TanStack Query es una herramienta potente para gestionar datos remotos en Angular, ofreciendo caché automático, sincronización en segundo plano y control de estados de carga y errores, además de funciones avanzadas como prefetching y ejecución paralela de queries. Aunque apenas hemos visto la punta del iceberg, TanStack proporciona muchas otras funcionalidades que pueden simplificar la gestión de datos y mejorar la experiencia del usuario.
A pesar de estar en fase experimental, su adopción permite reducir la complejidad del frontend y ofrece claridad, eficiencia y mejores prácticas, posicionándose como una alternativa moderna frente a soluciones tradicionales como Redux o servicios, Observables y gestión manual del estado.