Busca en todas las páginas de la documentación
🤖 Read the SystemsArchitect.io Blog for over 100+ cloud architecture articles 🔥
SWR usa una caché en memoria por defecto. Personaliza el proveedor de caché para almacenamiento persistente, diseña tu estrategia de claves para maximizar los aciertos de caché y aprovecha la deduplicación para evitar solicitudes de red redundantes.
"use client";
import { SWRConfig } from "swr";
function App({ children }: { children: React.ReactNode }) {
return (
<SWRConfig
value={{
provider: () => new Map(), // Caché en memoria predeterminada
dedupingInterval: 2000, // Deduplica solicitudes dentro de 2s
}}
>
{children}
</SWRConfig>
);
}"use client";
import { SWRConfig, Cache } from "swr";
import useSWR from "swr";
// Caché persistente respaldada por localStorage
function localStorageProvider(): Cache {
const map = new Map<string, any>(
JSON.parse(localStorage.getItem("swr-cache") || "[]")
);
// Persiste en localStorage antes de descargar la página
window.addEventListener("beforeunload", () => {
const appCache = JSON.stringify(Array.from(map.entries()));
localStorage.setItem("swr-cache", appCache);
});
return {
get: (key: string) => map.get(key),
set: (key: string, value: any) => map.set(key, value),
delete: (key: string) => map.delete(key),
keys: () => map.keys(),
};
}
export function CachedApp({ children }: { children: React.ReactNode }) {
return (
<SWRConfig value={{ provider: localStorageProvider }}>
{children}
</SWRConfig>
);
}
// Los componentes se benefician automáticamente de la caché persistente
function UserProfile() {
const { data } = useSWR("/api/me", (url) => fetch(url).then((r) => r.json()));
return <div>{data?.name}</div>;
}useSWR(key) se asigna directamente a una entrada de caché.Map que vive en memoria y se reinicia al recargar la página.dedupingInterval ms, solo se ejecuta un fetch. Todos los hooks reciben la misma promesa.provider en SWRConfig se invoca una vez al montar y debe devolver un objeto compatible con Cache.Diseño de claves para eficiencia de caché:
// Bien: claves estables y serializables
useSWR(`/api/users/${id}`, fetcher);
useSWR(["/api/users", id, "posts"], fetcher);
// Mal: referencias de objetos inestables (no serializables)
useSWR({ url: "/api/users", id }, fetcher); // No cacheará correctamentePrecarga en caché:
import { preload } from "swr";
const fetcher = (url: string) => fetch(url).then((r) => r.json());
// Precarga al pasar el cursor o en prefetch de ruta
function ProductCard({ id }: { id: string }) {
const handleMouseEnter = () => {
preload(`/api/products/${id}`, fetcher);
};
return (
<a href={`/products/${id}`} onMouseEnter={handleMouseEnter}>
Ver producto
</a>
);
}Vaciar la caché:
import { useSWRConfig } from "swr";
function LogoutButton() {
const { cache } = useSWRConfig();
const handleLogout = () => {
// Borra todos los datos en caché al cerrar sesión
if (cache instanceof Map) {
cache.clear();
}
};
return <button onClick={handleLogout}>Cerrar sesión</button>;
}Caché con TTL:
function ttlProvider(): Cache {
const cache = new Map<string, { value: any; expiry: number }>();
const TTL = 5 * 60 * 1000; // 5 minutos
return {
get: (key: string) => {
const entry = cache.get(key);
if (!entry) return undefined;
if (Date.now() > entry.expiry) {
cache.delete(key);
return undefined;
}
return entry.value;
},
set: (key: string, value: any) => {
cache.set(key, { value, expiry: Date.now() + TTL });
},
delete: (key: string) => cache.delete(key),
keys: () => cache.keys(),
};
}Cache desde swr para tipar proveedores personalizados.provider espera () => Cache.import type { Cache } from "swr";
const provider = (): Cache => {
const map = new Map();
return {
get: (key: string) => map.get(key),
set: (key: string, value: any) => map.set(key, value),
delete: (key: string) => map.delete(key),
keys: () => map.keys(),
};
};dedupingInterval solo deduplica solicitudes concurrentes. No evita volver a obtener datos después de que expire el intervalo.["/api/users", id] se serializan para el almacenamiento en caché. El orden de los elementos importa: [a, b] y [b, a] son claves de caché diferentes.Cache completa, incluido keys(). Los métodos faltantes provocarán errores en tiempo de ejecución.localStorage tiene un límite de ~5MB. Las cachés grandes pueden fallar en silencio. Implementa manejo de errores en el método set de tu proveedor.SWRConfig en distintos niveles de anidación; cada proveedor crea su propio ámbito.| Enfoque | Ventajas | Desventajas |
|---|---|---|
| Caché Map predeterminada | Cero configuración, rápida | Se pierde al recargar |
| Proveedor de localStorage | Persiste entre sesiones | Límite de 5MB, la API síncrona bloquea el hilo principal |
| Proveedor de IndexedDB | Gran almacenamiento, asíncrono | Implementación más compleja |
| Sin caché (dedupingInterval: 0) | Datos siempre frescos | Más solicitudes de red |
SWR usa una instancia de Map en memoria por defecto. Se reinicia al recargar la página. No se necesita configuración para el almacenamiento en caché básico.
Implementa un proveedor de caché personalizado respaldado por localStorage o IndexedDB. El proveedor debe implementar la interfaz Cache (get, set, delete, keys). Persiste en beforeunload y rehidrata al inicializar.
dedupingInterval) evita solicitudes duplicadas concurrentes dentro de una ventana de tiempo.Sí. ["/api/users", id] y [id, "/api/users"] son claves de caché diferentes. SWR serializa los elementos del array en orden, por lo que cambiar el orden crea una entrada de caché distinta.
import { preload } from "swr";
const fetcher = (url: string) => fetch(url).then((r) => r.json());
// Precarga al pasar el cursor
const handleMouseEnter = () => {
preload(`/api/products/${id}`, fetcher);
};const { cache } = useSWRConfig();
const handleLogout = () => {
if (cache instanceof Map) {
cache.clear();
}
};No. Las referencias de objetos no son serializables por SWR. Usa strings o arrays como claves. useSWR({ url: "/api/users", id }, fetcher) no cacheará correctamente.
La escritura falla en silencio. Implementa manejo de errores en el método set de tu proveedor usando try/catch, y considera expulsar entradas antiguas o recurrir al almacenamiento en memoria.
import type { Cache } from "swr";
const provider = (): Cache => {
const map = new Map();
return {
get: (key: string) => map.get(key),
set: (key: string, value: any) => map.set(key, value),
delete: (key: string) => map.delete(key),
keys: () => map.keys(),
};
};La opción provider espera una función de tipo () => Cache. Importa Cache desde swr para tipar tu implementación personalizada. Los métodos faltantes de la interfaz (keys, delete) provocarán errores en tiempo de ejecución.
Almacena entradas con una marca de tiempo de expiración. En get, comprueba si la entrada ha expirado y devuelve undefined en ese caso. Esto obliga a SWR a tratarlo como un fallo de caché y volver a obtener los datos.
Revisado por Chris St. John·Última actualización: 7 jul 2026
🤖 Read the SystemsArchitect.io Blog for over 100+ cloud architecture articles 🔥