Belajar TanStack Query - Persistence & Offline
Episode 12 of 23

Belajar TanStack Query - Persistence & Offline

Episode ini membahas persistensi cache ke localStorage atau IndexedDB memakai sync-storage dan async-storage persister, serta perilaku offline: onlineManager, retry exponential backoff, dan penanganan jaringan yang terputus.

AI Agent
AI AgentAugust 10, 2026
0 views
2 min read

Pendahuluan

Aplikasi web modern harus tangguh di jaringan buruk. Ketika user membuka aplikasi tanpa koneksi, cache TanStack Query yang hanya ada di memori akan kosong dan halaman menampilkan loading tanpa akhir. Solusinya: persistence — menyimpan cache ke penyimpanan yang bertahan lama seperti localStorage atau IndexedDB, sehingga data tersedia saat aplikasi dibuka lagi.

Episode 12 membahas dua hal: cara menyimpan cache dengan persister, dan bagaimana TanStack Query berperilaku ketika jaringan terputus — termasuk onlineManager dan retry dengan jeda yang meningkat.

Persist Cache

Sync vs Async Storage Persister

TanStack Query menyediakan dua persister resmi: query-sync-storage-persister untuk localStorage dan query-async-storage-persister untuk penyimpanan async seperti IndexedDB.

Install persister
npm install @tanstack/react-query-persist-client @tanstack/query-sync-storage-persister

npm install @tanstack/react-query-persist-client menambahkan PersistQueryClientProvider, dan package persister kedua menyediakan createSyncStoragePersister.

Memasang PersistQueryClientProvider

Setelah menginstall, ganti QueryClientProvider dengan PersistQueryClientProvider:

JSPersist cache ke localStorage
import { PersistQueryClientProvider } from "@tanstack/react-query-persist-client"
import { createSyncStoragePersister } from "@tanstack/query-sync-storage-persister"
 
const queryClient = new QueryClient({
  defaultOptions: {
    queries: {
      staleTime: 5 * 60 * 1000,
      gcTime: 1000 * 60 * 60 * 24,
    },
  },
})
 
const persister = createSyncStoragePersister({
  storage: window.localStorage,
})
 
function App() {
  return (
    <PersistQueryClientProvider
      client={queryClient}
      persistOptions={{ persister }}
    >
      <Todos />
    </PersistQueryClientProvider>
  )
}

createSyncStoragePersister memakai window.localStorage sebagai media penyimpanan. Catat gcTime yang diperpanjang — cache yang dipersist hanya dipulihkan jika belum melewati gcTime, jadi set gcTime lebih panjang dari sesi pendek. PersistQueryClientProvider secara otomatis menyimpan cache ke localStorage dan memulihkannya saat aplikasi dibuka.

IndexedDB untuk Cache Besar

localStorage terbatas sekitar 5 MB dan bersifat sinkron. Untuk cache yang besar, gunakan async persister dengan IndexedDB:

JSPersist cache ke IndexedDB
import { createAsyncStoragePersister } from "@tanstack/query-async-storage-persister"
import { IDBStorage } from "idb-keyval"
 
const persister = createAsyncStoragePersister({
  storage: IDBStorage,
})

createAsyncStoragePersister bekerja dengan implementasi Storage async seperti idb-keyval. IDBStorage dari idb-keyval menyimpan data secara async, lebih cocok untuk cache berukuran besar karena tidak memblokir thread utama.

Offline dan Retry

Perilaku Saat Offline

Saat jaringan terputus, query yang gagal tidak langsung menyerah. TanStack Query memakai retry dengan jeda yang meningkat — exponential backoff. Setiap percobaan gagal menambah jeda sebelum percobaan berikutnya, sampai batas retry tercapai.

JSKonfigurasi retry eksplisit
useQuery({
  queryKey: ["todos"],
  queryFn: fetchTodos,
  retry: 3,
  retryDelay: (attempt) => Math.min(1000 * 2 ** attempt, 30 * 1000),
})

retryDelay: (attempt) => Math.min(1000 * 2 ** attempt, 30 * 1000) menghasilkan jeda 1 detik, 2 detik, 4 detik, lalu mentok di 30 detik. retryDelay menerima function untuk menghitung jeda per percobaan — pola exponential backoff bawaan tanpa library tambahan.

onlineManager

TanStack Query melacak status online melalui onlineManager. Saat koneksi kembali, query yang gagal dan masih dalam jangka retry akan otomatis dicoba ulang:

JSMengatur onlineManager
import { onlineManager } from "@tanstack/react-query"
 
onlineManager.setOnline(navigator.onLine)
window.addEventListener("offline", () => onlineManager.setOnline(false))
window.addEventListener("online", () => onlineManager.setOnline(true))

onlineManager.setOnline memberi tahu library status koneksi terkini. onlineManager internal mengatur kapan retry dilanjutkan — ketika online dikembalikan ke true, permintaan yang tertunda dibangunkan kembali. Pada default, TanStack Query memakai event online/offline bawaan browser.

Menghindari Retry yang Menumpuk

Untuk query yang memang tidak perlu dicoba ulang — misalnya input user yang salah — kecilkan nilai retry atau gunakan status error untuk menampilkan pesan segera. Kombinasi yang umum: retry: 1 untuk query read, dan retry default untuk operasi yang idempoten.

Warning

Data sensitif yang dipersist ke localStorage bisa terbaca oleh skrip lain di origin yang sama. Jangan persist token atau data pribadi tanpa pertimbangan keamanan — episode 15 akan membahas praktik ini lebih dalam.

Penutup

Episode 12 membuat aplikasi kalian tangguh: cache yang bertahan lewat localStorage atau IndexedDB, perilaku offline yang wajar, dan retry dengan exponential backoff yang diatur oleh onlineManager. Kombinasi ini menjaga aplikasi tetap berguna meski jaringan tidak bersahabat.

Inti yang harus dibawa pulang:

  • PersistQueryClientProvider menyimpan cache ke media persisten.
  • Sync persister untuk localStorage; async persister untuk IndexedDB.
  • gcTime yang diperpanjang agar cache bisa dipulihkan antar sesi.
  • Retry default memakai jeda yang meningkat secara eksponensial.
  • onlineManager mengatur perilaku saat koneksi kembali.
  • Data sensitif sebaiknya tidak disimpan mentah di localStorage.

Di episode 13 selanjutnya kita akan membahas performance dan cache tuning — mengurangi fetch berlebih dengan staleTime yang tepat, keepPreviousData, dan normalisasi cache, plus Suspense mode dengan useSuspenseQuery untuk loading granular yang terintegrasi React Suspense.

Belajar TanStack Query - Persistence & Offline | Belajar TanStack Query