Belajar TanStack - Query & Data Fetching
Episode 4 of 24

Belajar TanStack - Query & Data Fetching

Episode ini membuka inti TanStack Query: QueryClientProvider, hook useQuery, status isPending dan isError, pengaturan staleTime dan gcTime, error handling dengan retry, serta background refetching yang menyinkronkan data secara otomatis.

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

Pendahuluan

Setelah setup selesai di episode 3, inilah momen yang kalian tunggu: menulis query pertama. TanStack Query mengubah data fetching dari ritual useEffect yang berulang menjadi satu hook yang melacak status, cache, dan sinkronisasi secara otomatis.

Episode 4 membedah QueryClientProvider, hook useQuery, status yang dikembalikan, pengaturan staleTime dan gcTime, error handling dengan retry, serta background refetching. Semua konsep di episode 2 kini dipraktikkan.

Di akhir episode ini, kalian akan memahami alur kerja query di level komponen dan tahu cara mengatur cache agar aplikasi terasa cepat tanpa kerja ekstra.

QueryClient dan QueryClientProvider

Membungkus Aplikasi dengan Provider

queryClient dibuat sekali lalu disuntikkan ke pohon komponen lewat QueryClientProvider. Tanpa provider ini, semua useQuery akan gagal.

JSmain.tsx dengan QueryClientProvider
import { QueryClient, QueryClientProvider } from "@tanstack/react-query"
import { StrictMode } from "react"
import { createRoot } from "react-dom/client"
import App from "./App"
 
const queryClient = new QueryClient()
 
createRoot(document.getElementById("root")).render(
  <StrictMode>
    <QueryClientProvider client={queryClient}>
      <App />
    </QueryClientProvider>
  </StrictMode>
)

<QueryClientProvider client={queryClient}> membungkus seluruh aplikasi. Mulai sekarang, semua hook query di dalam pohon ini memakai cache yang sama.

Hook useQuery dan Statusnya

Membaca Status Query

useQuery menerima objek konfigurasi dengan queryKey dan queryFn, lalu mengembalikan status dan data:

JSHook useQuery pertama
import { useQuery } from "@tanstack/react-query"
 
function Todos() {
  const { data, isPending, isError, error } = useQuery({
    queryKey: ["todos"],
    queryFn: async () => {
      const res = await fetch("/api/todos")
      if (!res.ok) throw new Error("Gagal memuat todos")
      return res.json()
    },
  })
 
  if (isPending) return <p>Memuat todos...</p>
  if (isError) return <p>Error: {error.message}</p>
 
  return <ul>{data.map((todo) => <li key={todo.id}>{todo.title}</li>)}</ul>
}

queryKey: ["todos"] adalah identitas query — unik dan menjadi dasar cache. queryFn mengembalikan promise; saat resolved, hasilnya masuk cache. Status isPending menandakan belum ada data, dan isError menandakan terjadi error.

Mengapa queryKey Penting

Dua komponen yang memakai queryKey identik akan berbagi satu query dan satu cache. Ini deduplication: request yang sama tidak dikirim dua kali, dan data langsung tersedia untuk komponen kedua tanpa loading.

staleTime, gcTime, dan Refetching

Data Basi vs Data Terhapus

staleTime menentukan berapa lama data dianggap segar (belum perlu di-fetch ulang). gcTime menentukan berapa lama data tersimpan di cache setelah tidak dipakai. Keduanya sering tertukar:

JSKontrol cache dengan staleTime dan gcTime
const { data } = useQuery({
  queryKey: ["profil"],
  queryFn: ambilProfil,
  staleTime: 60_000,
  gcTime: 5 * 60_000,
})

Dengan staleTime: 60_000, dalam satu menit data dipakai langsung dari cache tanpa request baru. gcTime: 5 * 60_000 membuat data bertahan lima menit setelah komponen melepasnya.

Background Refetching

Secara default, query yang stale di-fetch ulang setiap window kembali fokus dan saat koneksi kembali online. Perilaku ini bisa diatur lewat refetchOnWindowFocus dan refetchOnReconnect. Hasilnya, data selalu tersinkron tanpa tombol refresh manual.

Error Handling dan Retry

Retry dengan Backoff

Saat queryFn melempar error, TanStack Query mencoba ulang dengan jeda yang naik secara eksponensial. Kalian bisa mengontrol jumlah percobaan dan penundaan:

JSMengatur retry dan refetch manual
const { data, refetch } = useQuery({
  queryKey: ["cekout"],
  queryFn: ambilCekout,
  retry: 3,
  retryDelay: (attempt) => Math.min(1000 * 2 ** attempt, 30_000),
})
 
return (
  <button onClick={() => refetch()}>Muat ulang</button>
)

retry: 3 membatasi tiga kali percobaan ulang. retryDelay menghitung jeda eksponensial dengan batas maksimum 30 detik. refetch dipanggil manual lewat tombol, memaksa query di-fetch ulang sekarang juga.

React Query DevTools

Melihat Cache dan Status Secara Visual

TanStack Query menyediakan devtools yang menampilkan semua query, statusnya, data cache, dan tombol untuk menguji refetch serta invalidate:

JSAktifkan React Query DevTools
import { ReactQueryDevtools } from "@tanstack/react-query-devtools"
 
<QueryClientProvider client={queryClient}>
  <App />
  <ReactQueryDevtools initialIsOpen={false} />
</QueryClientProvider>

<ReactQueryDevtools /> menambahkan panel di pojok browser. Dari panel ini kalian bisa melihat staleTime efektif, menguji invalidasi, dan memeriksa isi cache — sangat berguna saat debugging di episode 14.

Tip

Buka React Query DevTools lalu klik setiap query untuk melihat isStale dan isFetching. Dua status inilah kunci memahami kapan data di-fetch ulang.

Penutup

Episode 4 menutup fondasi data fetching: membungkus aplikasi dengan QueryClientProvider, membaca data lewat useQuery dengan status isPending dan isError, mengatur staleTime dan gcTime, menangani error dengan retry, serta memantau semua lewat React Query DevTools.

Inti yang harus dibawa pulang:

  • QueryClient dibuat sekali dan disuntikkan lewat QueryClientProvider.
  • queryKey adalah identitas query sekaligus dasar deduplication.
  • staleTime mengatur kesegaran data; gcTime mengatur masa hidup cache.
  • Background refetching berjalan saat window fokus atau koneksi pulih.
  • retry dan retryDelay mengontrol percobaan ulang saat error.
  • React Query DevTools menampilkan status seluruh query.

Di episode 5 selanjutnya kita akan membahas data mutations dan optimistic updatesuseMutation untuk mengubah data, invalidasi query setelah mutasi, optimistic update dengan rollback, serta paginated data dan infinite scrolling dengan useInfiniteQuery. Siapkan aplikasi belajar-tanstack kalian, karena kita mulai menulis mutasi pertama!

Belajar TanStack - Query & Data Fetching | Belajar TanStack