Belajar TanStack Query - Konsep Dasar & Arsitektur Utama
Episode 2 of 23

Belajar TanStack Query - Konsep Dasar & Arsitektur Utama

Episode ini membangun model mental TanStack Query: perbedaan query dan mutation, perjalanan query key menuju cache, konsep observer, staleTime dan gcTime, structural sharing, serta komponen utama QueryClient, provider, dan hooks yang tersedia.

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

Pendahuluan

Sebelum menulis kode, bangun dulu model mental yang benar. TanStack Query bukan sekadar kumpulan hook — dia adalah sistem cache yang lengkap dengan alur kehidupan data yang jelas. Kalau kalian memahami arsitekturnya, semua opsi konfigurasi di episode berikutnya akan terasa masuk akal, bukan sekadar dihafal.

Episode 2 membedah dua model operasi utama (query dan mutation), cara data mengalir dari query key menuju cache, serta komponen-komponen yang membentuk library ini. Ini adalah fondasi arsitektural dari seluruh series.

Model Data: Query dan Mutation

Query: Membaca Data

Sebuah query adalah operasi baca yang identik dengan request GET. Query dideklarasikan dengan dua hal: queryKey sebagai identitas unik, dan queryFn sebagai fungsi yang mengambil data. Contoh mental modelnya:

JSMental model query
useQuery({
  queryKey: ["todos"],
  queryFn: fetchTodos,
})

Data hasil query disimpan di cache dengan kunci ["todos"]. Selama query yang sama digunakan di mana pun, data yang sama dibaca dari cache — tidak ada double fetch.

Mutation: Menulis Data

Sebuah mutation adalah operasi tulis — POST, PUT, PATCH, atau DELETE. Mutation tidak disimpan di cache dengan cara yang sama seperti query, karena dia hanya terjadi sekali. Tugas mutation adalah menulis data ke server, lalu memberi tahu cache agar diperbarui.

JSMental model mutation
useMutation({
  mutationFn: createTodo,
})

Perbedaan mendasar: query bersifat deklaratif dan berulang, mutation imperatif dan sekali jalan. useMutation dipanggil lewat method mutate pada event handler, sedangkan useQuery berjalan otomatis saat komponen di-mount. Keduanya berbagi satu hal — keduanya berjalan di atas cache global yang sama.

Cara Kerja di Balik Layar

Alur Query Key Menuju Cache

Saat komponen memanggil useQuery, terjadi alur yang bisa diringkas dalam satu diagram:

Alur query di TanStack Query
queryKey → observer → fetch → cache → komponen

queryKey adalah input pertama: dia menentukan slot cache mana yang dibaca. Setiap query yang memakai key sama berbagi satu entri cache. Inilah yang membuat deduplication bekerja — dua komponen dengan key identik tidak melakukan dua fetch.

Observer dan Deduplication

Setiap panggilan useQuery menciptakan observer. Jika banyak komponen memakai key yang sama, mereka semua berlangganan pada satu entri cache yang sama. Library mendeteksi ini dan hanya melakukan satu fetch untuk key tersebut, lalu membagikan hasilnya ke semua observer. Ketika satu observer di-unmount, yang lain tetap dapat data dari cache tanpa fetch baru.

staleTime dan gcTime

Dua pengatur waktu yang paling sering disalahpahami:

  • staleTime: berapa lama data dianggap segar sebelum di-refetch di latar belakang.
  • gcTime: berapa lama cache disimpan di memori sebelum dibuang ketika tidak ada observer.

Data bisa "segar tapi tidak terpakai" dan "terpakai tapi basi". Keduanya diatur terpisah, dan episode 7 akan membahasnya secara mendalam.

Structural Sharing

Saat cache diperbarui, TanStack Query tidak membuat objek baru secara membabi buta. Structural sharing memastikan bahwa bagian struktur data yang tidak berubah tetap mereferensi objek yang sama, sehingga render ulang dan memoization tetap efisien.

JSStructural sharing menjaga referensi
const a = { todos: [], meta: { page: 1 } }
const b = produce(a, (draft) => {
  draft.meta.page = 2
})
a.todos === b.todos // true, array todos tidak disentuh

Perbandingan a.todos === b.todos bernilai true karena structural sharing — referensi array yang tidak berubah dipertahankan. produce di atas hanya ilustrasi dari hasil akhir; mekanisme internal TanStack Query berbeda tapi efeknya sama.

Komponen Utama Library

QueryClient dan QueryClientProvider

QueryClient adalah tempat semua cache dan konfigurasi hidup. Dia dibuat sekali dan diberikan ke seluruh aplikasi lewat provider:

JSQueryClient dan provider
import { QueryClient, QueryClientProvider } from "@tanstack/react-query"
 
const queryClient = new QueryClient()
 
export function App() {
  return (
    <QueryClientProvider client={queryClient}>
      <Todos />
    </QueryClientProvider>
  )
}

new QueryClient() menciptakan satu instance cache global untuk aplikasi kalian. QueryClientProvider menyuntikkan instance itu ke seluruh pohon komponen sehingga semua hooks bisa mengaksesnya.

Kumpulan Hooks

Di atas QueryClient, library menyediakan hooks utama:

  • useQuery untuk membaca satu query.
  • useMutation untuk operasi tulis.
  • useQueries untuk beberapa query paralel sekaligus.
  • useInfiniteQuery untuk data yang dimuat bertahap.
  • useQueryClient untuk mengakses QueryClient dari komponen.

Semua hooks ini akan dipecah satu per satu di episode-episode berikutnya.

Devtools

Terakhir, ada React Query Devtools — panel yang menampilkan seluruh cache, status tiap query, jumlah fetch, dan tombol untuk meng-invalidate secara manual. Devtools adalah mata dan telinga kalian saat debugging, dan akan dibahas detail di episode 17.

Tip

Mulai sekarang biasakan membayangkan setiap query sebagai sebuah slot di cache yang punya identitas berupa query key. Semua perilaku TanStack Query — refetch, invalidation, optimistic update — sebenarnya adalah manipulasi pada slot-slot tersebut.

Penutup

Episode 2 membangun model mental arsitektur TanStack Query: query untuk membaca, mutation untuk menulis, cache global yang diidentifikasi oleh query key, observer yang melakukan deduplication, serta pengatur waktu staleTime dan gcTime yang terpisah.

Inti yang harus dibawa pulang:

  • Query adalah operasi baca; mutation adalah operasi tulis.
  • queryKey menentukan slot cache; key identik berarti data dibagikan.
  • Observer membuat deduplication terjadi otomatis.
  • staleTime mengatur kesegaran; gcTime mengatur pembuangan cache.
  • Structural sharing menjaga referensi data yang tidak berubah.
  • QueryClient plus provider adalah jantung library ini.

Di episode 3 selanjutnya kita akan membahas setup dan konfigurasi QueryClient — cara membuat instance dengan default options, membungkus aplikasi dengan QueryClientProvider, serta mengatur staleTime, retry, refetchOnWindowFocus, dan gcTime secara global. Ini langkah pertama yang benar-benar menulis kode TanStack Query.