Belajar TanStack Query - Staleness & Refetching
Episode 7 of 23

Belajar TanStack Query - Staleness & Refetching

Episode ini menjelaskan konsep fresh versus stale, perbedaan staleTime dan gcTime, serta semua mekanisme refetch otomatis: refetchOnWindowFocus, refetchOnReconnect, refetchInterval untuk polling, dan method refetch manual.

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

Pendahuluan

Salah satu fitur TanStack Query yang paling terasa di aplikasi nyata adalah refetch otomatis: data di-refresh di latar belakang tanpa kalian menulis satu baris pun. Tapi otomatis bukan berarti tidak bisa dikendalikan — justru karena ada banyak tombol, kalian perlu tahu mana yang ditekan kapan.

Episode 7 mengupas dua pengatur waktu yang paling sering tertukar (staleTime dan gcTime), lalu semua mekanisme refetch otomatis dan manual yang tersedia.

Fresh vs Stale

Konsep Kesegaran

Data di TanStack Query berada dalam dua kondisi: fresh dan stale. Data fresh dianggap cukup baru untuk dipakai tanpa refetch. Data stale dianggap bisa diperbarui dan akan di-refetch ketika ada trigger. Batas antara keduanya ditentukan oleh staleTime:

JSMenentukan staleTime
useQuery({
  queryKey: ["todos"],
  queryFn: fetchTodos,
  staleTime: 30 * 1000,
})

staleTime: 30 * 1000 berarti data dianggap segar selama 30 detik setelah fetch selesai. Setelah itu data menjadi stale, dan trigger refetch mana pun akan mengambil versi terbaru. staleTime dihitung sejak data terakhir berhasil diambil.

staleTime vs gcTime

Kedua pengatur waktu ini sering tertukar. Perbedaan intinya:

staleTime vs gcTime
staleTime → kapan data dianggap basi (tetap di cache, siap di-refetch)
gcTime    → kapan cache dibuang dari memori (data hilang, fetch ulang)

Ringkasan staleTime kapan data dianggap basi menegaskan bahwa data stale masih tersedia di cache dan langsung ditampilkan, hanya saja dianggap perlu disegarkan. gcTime yang berjalan saat tidak ada observer akan menghapus data sepenuhnya dari memori — berbeda total dengan sekadar menandainya basi.

Refetch Otomatis

refetchOnWindowFocus

Saat user kembali ke tab browser, TanStack Query secara default me-refetch semua query yang stale. Ini membuat aplikasi selalu segar setelah user absen:

JSRefetch saat window fokus
useQuery({
  queryKey: ["todos"],
  queryFn: fetchTodos,
  refetchOnWindowFocus: true,
})

Aktif secara default. Atur ke false jika aplikasi kalian lebih suka kontrol penuh, atau atur di QueryClient global seperti episode 3.

refetchOnReconnect

Saat koneksi jaringan kembali setelah terputus, query stale di-refetch otomatis. Fitur ini penting untuk aplikasi mobile dan lingkungan dengan koneksi tidak stabil:

JSRefetch saat koneksi kembali
refetchOnReconnect: true,

refetchInterval: Polling

Untuk data yang terus berubah — harga, status job, skor pertandingan — gunakan polling dengan refetchInterval:

JSPolling setiap 5 detik
const { data } = useQuery({
  queryKey: ["job-status"],
  queryFn: fetchJobStatus,
  refetchInterval: 5000,
})

refetchInterval: 5000 melakukan refetch setiap 5 detik selama ada observer aktif. refetchIntervalInBackground bisa ditambahkan untuk polling bahkan ketika tab tidak fokus, tapi pastikan tidak membebani server.

Refetch Manual

Method refetch

Kadang trigger otomatis tidak cukup — misalnya tombol "Muat Ulang" yang dipencet user. useQuery mengembalikan method refetch:

JSRefetch manual
function Todos() {
  const { data, refetch, isFetching } = useQuery({
    queryKey: ["todos"],
    queryFn: fetchTodos,
  })
 
  return (
    <div>
      <button onClick={() => refetch()} disabled={isFetching}>
        Muat Ulang
      </button>
      <ul>{data?.map((todo) => <li key={todo.id}>{todo.title}</li>)}</ul>
    </div>
  )
}

refetch() memaksa pengambilan data baru, dan isFetching menandakan apakah fetch sedang berjalan. Perhatikan bahwa refetch hanya mengambil data jika query dalam kondisi stale kecuali dipaksa — untuk perilaku ini TanStack Query menangani detilnya secara otomatis.

Menggabungkan Semua Trigger

Ingat kapan tiap trigger bekerja:

Trigger refetch
mount komponen (query stale) → refetch
window focus kembali        → refetchOnWindowFocus
jaringan reconnect           → refetchOnReconnect
interval polling             → refetchInterval
tombol / event               → refetch() manual

Ringkasan mount komponen (query stale) → refetch menampilkan kasus paling umum: komponen di-mount dan datanya sudah basi, maka query di-refetch. Trigger- trigger lain hanyalah variasi dari prinsip yang sama.

Tip

Aturan praktis: set staleTime sesuai seberapa sering data kalian berubah, bukan seberapa sering komponen di-mount. Jika data jarang berubah, staleTime besar akan menghemat banyak request tanpa mengorbankan konsistensi.

Penutup

Episode 7 memberi kalian kendali penuh atas kapan dan bagaimana data disegarkan. Kalian memahami perbedaan staleTime dan gcTime, trigger otomatis seperti window focus dan reconnect, polling dengan refetchInterval, serta refetch manual.

Inti yang harus dibawa pulang:

  • staleTime menentukan kapan data dianggap basi; gcTime menentukan kapan cache dibuang.
  • Data stale tetap tersedia di cache dan langsung ditampilkan.
  • refetchOnWindowFocus dan refetchOnReconnect aktif secara default.
  • refetchInterval untuk polling data yang sering berubah.
  • Method refetch() untuk trigger manual dari event user.
  • Trigger refetch hanya bekerja pada query yang stale.

Di episode 8 selanjutnya kita akan membahas dependent dan parallel queries — mengambil beberapa query sekaligus dengan useQueries, serta query yang menunggu hasil query lain dengan opsi enabled. Ini pola penting untuk halaman dashboard dan data yang saling bergantung.

Belajar TanStack Query - Staleness & Refetching | Belajar TanStack Query