Mejora el rendimiento de Next.js con TanStack Query (React Query)
Cómo TanStack Query mejora el rendimiento de Next.js: caché, revalidación en segundo plano, mutaciones y SSR/SSG hidratado.

Gestionar correctamente el estado del servidor es una de las palancas de rendimiento más infravaloradas en Next.js. Con patrones manuales (fetch + useEffect) aparece código repetido, condiciones de carrera y múltiples solicitudes idénticas.
TanStack Query convierte ese caos en una capa declarativa: define clave, función y política de caducidad; el framework hace el resto.
¿Por qué el fetching suele ser un cuello de botella oculto?
Patrones problemáticos comunes:
- Repetir la misma petición en componentes distintos.
- Hacer transiciones de página completas para cambios puntuales.
- Usar estado global para datos del servidor (abstracción incorrecta).
- No aprovechar un caché compartido entre navegaciones.
- Refetch agresivo al volver el foco → presión sobre la API.
Resultado: más latencia percibida y navegación menos fluida.
TanStack Query estandariza frescura, caducidad e invalidación → menos sorpresas.
Lo que obtienes con TanStack Query
- De-duplicación y caché compartido.
- Stale-While-Revalidate: pintado inmediato + actualización silenciosa.
- Recolección automática de queries no usados.
- Invalidation específico tras mutaciones.
- Hidratación SSR/SSG para mejor primer render y SEO.
Instalación
yarn add @tanstack/react-query
Compatible con App Router (Next.js 13/14). No dependemos de APIs nuevas de 15+.
Proveedor global del QueryClient
"use client";
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
import { useState, ReactNode } from "react";
export function QueryProviders({ children }: { children: ReactNode }) {
const [queryClient] = useState(() => new QueryClient());
return <QueryClientProvider client={queryClient}>{children}</QueryClientProvider>;
}
En app/layout.tsx:
import { QueryProviders } from "@/app/query-providers";
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<html lang="es">
<body>
<QueryProviders>{children}</QueryProviders>
</body>
</html>
);
}
Fetch imperativo vs declarativo
Sin TanStack Query:
const [posts, setPosts] = useState([]);
const [loading, setLoading] = useState(true);
useEffect(() => {
let cancelado = false;
fetch("/api/posts")
.then(r => r.json())
.then(d => { if (!cancelado) { setPosts(d); setLoading(false); } });
return () => { cancelado = true; };
}, []);
Con TanStack Query:
"use client";
import { useQuery } from "@tanstack/react-query";
async function fetchPosts() {
const res = await fetch("https://jsonplaceholder.typicode.com/posts");
if (!res.ok) throw new Error("Error al obtener posts");
return res.json();
}
export function PostsList() {
const { data, isLoading, isError } = useQuery({
queryKey: ["posts"],
queryFn: fetchPosts,
staleTime: 60_000,
});
if (isLoading) return <p>Cargando…</p>;
if (isError) return <p>No se pudieron cargar los datos.</p>;
return <ul>{data.map((p: any) => <li key={p.id}>{p.title}</li>)}</ul>;
}
Beneficios: menos código, reutilización instantánea de caché, menos solicitudes.
Mutaciones e invalidación
import { useMutation, useQueryClient } from "@tanstack/react-query";
export function AddTodoButton() {
const qc = useQueryClient();
const mutation = useMutation({
mutationFn: async (nuevo: { title: string }) => {
await fetch("/api/todos", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(nuevo),
});
},
onSuccess: () => qc.invalidateQueries({ queryKey: ["todos"] }),
});
return (
<button onClick={() => mutation.mutate({ title: "Aprender TanStack Query" })}>
{mutation.isPending ? "Guardando…" : "Añadir"}
</button>
);
}
Secuencia clara → acción usuario → mutación → invalidación dirigida → UI fresca.
Hidratación SSR / SSG (pre 15)
// pages/posts.tsx
import { QueryClient, dehydrate } from "@tanstack/react-query";
import { useQuery } from "@tanstack/react-query";
async function fetchPosts() {
const r = await fetch("https://jsonplaceholder.typicode.com/posts");
return r.json();
}
export async function getStaticProps() {
const qc = new QueryClient();
await qc.prefetchQuery({ queryKey: ["posts"], queryFn: fetchPosts });
return { props: { dehydratedState: dehydrate(qc) }, revalidate: 3600 };
}
export default function PostsPage() {
const { data } = useQuery({ queryKey: ["posts"], queryFn: fetchPosts });
return (
<main>
<h1>Todos los posts</h1>
<ul>{data?.map((p: any) => <li key={p.id}>{p.title}</li>)}</ul>
</main>
);
}
Consejos de rendimiento
- Ajusta
staleTimepor dominio de datos. - Desactiva
refetchOnWindowFocussi no aporta valor. - Prefetch en hover de enlaces clave.
- Invalidación granular > invalidación global.
- Centraliza claves en un helper.
- Usa actualizaciones optimistas para UX de baja latencia.
Por qué lo usamos en Aniq‑UI
- Menos boilerplate para quien compra la plantilla.
- Mejor sensación de velocidad entre rutas.
- Separa claramente estado de servidor y UI.
- Ayuda a Core Web Vitals.
Conclusión
TanStack Query convierte efectos dispersos en una capa de caché consistente y escalable. Es una apuesta segura para proyectos que deben mantenerse en el tiempo y plantillas reutilizables.
Mira ejemplos reales en plantillas Next.js listas para producción en Aniq‑UI.com.
Palabras clave SEO: rendimiento Next.js, React Query Next.js, TanStack Query, plantillas Next.js, caché Next.js, fetching datos Next.js
¿Encontró útil este artículo?
También te puede interesar

Optimización de rendimiento en Next.js: Guía práctica para acelerar tus aplicaciones
Aprende a acelerar aplicaciones Next.js con optimización de imágenes, división de código, generación estática, carga de fuentes y reducción del tamaño del bundle.

Cómo integrar next-intl en Next.js 15 para internacionalización: Guía paso a paso
Tutorial paso a paso para integrar next-intl para traducción en un proyecto Next.js 15.

Plantillas gratuitas de páginas de aterrizaje
Explora tres plantillas gratuitas y listas para producción—perfectas para agencias, sitios corporativos y startups SaaS. Construidas con Next.js 15.2.4 y Tailwind CSS para un rendimiento ultrarrápido y diseño moderno.