Características y Ventajas
Características y Ventajas de TanStack Query
Section titled “Características y Ventajas de TanStack Query”TanStack Query no es solo otra librería de fetching de datos. Es una solución completa que aporta características avanzadas que mejoran significativamente la experiencia de desarrollo y del usuario final.
🚀 Características Principales
Section titled “🚀 Características Principales”1. Cache Automático e Inteligente
Section titled “1. Cache Automático e Inteligente”El cache de TanStack Query es su característica más poderosa:
// Primera vez - fetch desde el servidorconst { data } = useQuery({ queryKey: ['user', 1], queryFn: () => fetchUser(1)});
// Otras veces - desde cache instantáneoconst { data } = useQuery({ queryKey: ['user', 1], // Misma key = mismos datos queryFn: () => fetchUser(1)});
Beneficios del Cache:
- ⚡ Respuesta instantánea para datos ya cargados
- 🔄 Sincronización automática entre componentes
- 💾 Persistencia opcional entre sesiones
- 🎯 Invalidación inteligente cuando es necesario
2. Background Refetching
Section titled “2. Background Refetching”Los datos se actualizan automáticamente en segundo plano:
const { data } = useQuery({ queryKey: ['posts'], queryFn: fetchPosts, staleTime: 5 * 60 * 1000, // 5 minutos refetchOnWindowFocus: true, // Refetch al enfocar ventana refetchInterval: 30000 // Refetch cada 30 segundos});
Cuándo se actualiza automáticamente:
- 🔍 Cuando la ventana recupera el foco
- 🌐 Cuando se reconecta la red
- ⏰ En intervalos configurables
- 🔄 Cuando se considera que los datos están “stale”
3. Deduplicación de Peticiones
Section titled “3. Deduplicación de Peticiones”Múltiples componentes pueden usar la misma query sin duplicar peticiones:
// Componente Afunction UserProfile() { const { data } = useQuery({ queryKey: ['user', userId], queryFn: () => fetchUser(userId) });}
// Componente B (se ejecuta simultáneamente)function UserSettings() { const { data } = useQuery({ queryKey: ['user', userId], // Misma key! queryFn: () => fetchUser(userId) // Solo se ejecuta UNA vez });}
4. Estados Granulares
Section titled “4. Estados Granulares”Control preciso sobre todos los estados de la petición:
const { data, isLoading, // Primera carga isFetching, // Cualquier petición en chapter isStale, // Si los datos están obsoletos isError, // Si hay error error, // El error específico failureCount, // Número de reintentos fallidos refetch // Función para recargar} = useQuery({ queryKey: ['data'], queryFn: fetchData});
// UI granular basada en estadosif (isLoading) return <Skeleton />;if (isError) return <ErrorBoundary error={error} />;if (isFetching && !isLoading) return <LoadingIndicator />;
5. Retry Automático
Section titled “5. Retry Automático”Reintentos inteligentes con backoff exponencial:
const { data } = useQuery({ queryKey: ['flaky-api'], queryFn: fetchFlakyData, retry: 3, // Reintentar 3 veces retryDelay: attemptIndex => Math.min(1000 * 2 ** attemptIndex, 30000)});
6. Mutaciones Optimistas
Section titled “6. Mutaciones Optimistas”Actualiza la UI inmediatamente, antes de confirmar con el servidor:
const updateUser = useMutation({ mutationFn: updateUserAPI, onMutate: async (newUser) => { // Actualización optimista queryClient.setQueryData(['user', userId], newUser); }, onError: (err, newUser, context) => { // Rollback si falla queryClient.setQueryData(['user', userId], context.previousUser); }});
💡 Ventajas Principales
Section titled “💡 Ventajas Principales”1. Experiencia de Usuario Superior
Section titled “1. Experiencia de Usuario Superior”// Sin TanStack Query: Loading en cada navegaciónfunction ProductList() { const [products, setProducts] = useState([]); const [loading, setLoading] = useState(true);
useEffect(() => { // Siempre loading al montar setLoading(true); fetchProducts().then(data => { setProducts(data); setLoading(false); }); }, []);}
// Con TanStack Query: Datos instantáneos desde cachefunction ProductList() { const { data: products, isLoading } = useQuery({ queryKey: ['products'], queryFn: fetchProducts }); // isLoading solo es true la primera vez}
2. Reducción Dramática de Código
Section titled “2. Reducción Dramática de Código”Funcionalidad | Sin TanStack Query | Con TanStack Query |
---|---|---|
Fetching básico | ~20 líneas | ~5 líneas |
Cache manual | ~50 líneas | 0 líneas (automático) |
Retry logic | ~30 líneas | 1 línea de config |
Loading states | ~15 líneas | Incluido automáticamente |
Error handling | ~20 líneas | Incluido automáticamente |
3. Performance Optimizada
Section titled “3. Performance Optimizada”// Antes: N peticiones duplicadasfunction App() { return ( <div> <Header /> {/* fetchUser() */} <Sidebar /> {/* fetchUser() */} <Profile /> {/* fetchUser() */} </div> );}
// Después: 1 petición, 3 componentes actualizadosfunction App() { return ( <div> <Header /> {/* useQuery(['user']) */} <Sidebar /> {/* useQuery(['user']) - desde cache */} <Profile /> {/* useQuery(['user']) - desde cache */} </div> );}
4. Developer Experience Excepcional
Section titled “4. Developer Experience Excepcional”DevTools Potentes
Section titled “DevTools Potentes”// Instalar React Query DevToolsimport { ReactQueryDevtools } from '@tanstack/react-query-devtools';
function App() { return ( <> <MyApp /> <ReactQueryDevtools initialIsOpen={false} /> </> );}
TypeScript de Primera Clase
Section titled “TypeScript de Primera Clase”// Inferencia automática de tiposconst { data } = useQuery({ queryKey: ['user', userId], queryFn: (): Promise<User> => fetchUser(userId) // data es automáticamente de tipo User | undefined});
5. Escalabilidad
Section titled “5. Escalabilidad”TanStack Query escala naturalmente:
// Simple: Una queryconst { data: user } = useQuery({ queryKey: ['user'], queryFn: fetchUser});
// Complejo: Queries dependientesconst { data: user } = useQuery({ queryKey: ['user'], queryFn: fetchUser});
const { data: posts } = useQuery({ queryKey: ['posts', user?.id], queryFn: () => fetchUserPosts(user.id), enabled: !!user?.id // Solo ejecutar si user existe});
🆚 Comparación con Alternativas
Section titled “🆚 Comparación con Alternativas”vs. useState + useEffect
Section titled “vs. useState + useEffect”Aspecto | useState + useEffect | TanStack Query |
---|---|---|
Código requerido | 15-30 líneas | 3-5 líneas |
Cache | Manual | Automático |
Deduplicación | No | Sí |
Background updates | Manual | Automático |
Error handling | Manual | Automático |
Loading states | Manual | Automático |
vs. Redux Toolkit Query
Section titled “vs. Redux Toolkit Query”Aspecto | RTK Query | TanStack Query |
---|---|---|
Curva de aprendizaje | Alta | Media |
Bundle size | ~50kb | ~13kb |
Cache invalidation | Manual/Tags | Automático/Manual |
DevTools | Redux DevTools | Query DevTools |
Framework agnostic | No (Redux) | Sí |
vs. SWR
Section titled “vs. SWR”Aspecto | SWR | TanStack Query |
---|---|---|
API | Más simple | Más completa |
Mutations | Básicas | Avanzadas |
DevTools | No | Excelentes |
Infinite queries | Limitado | Completo |
Parallel queries | Manual | Automático |
🎯 Casos de Uso Ideales
Section titled “🎯 Casos de Uso Ideales”TanStack Query es perfecto para:
✅ Aplicaciones data-intensive (dashboards, admin panels)
✅ Apps con mucha navegación (SPAs complejas)
✅ Datos que cambian frecuentemente (feeds, notificaciones)
✅ Aplicaciones colaborativas (múltiples usuarios)
✅ Apps mobile-first (conexiones intermitentes)
❌ No usar para:
- Aplicaciones muy simples con pocas peticiones
- Estado puramente local (formularios, UI state)
- Aplicaciones estáticas sin APIs
Próximo paso: Estado local y del servidor