Belajar TanStack - Konsep Dasar & Arsitektur Utama
Episode 2 of 24

Belajar TanStack - Konsep Dasar & Arsitektur Utama

Episode ini membedah arsitektur di balik TanStack: query client dan cache di Query, sistem kolom dan row model di Table, state management serta loader di Router, dan cara virtualizer mengukur viewport di Virtual.

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

Pendahuluan

Episode 1 sudah menjelaskan apa yang TanStack pecahkan. Sekarang masuk lebih dalam: bagaimana library ini bekerja di balik layar. Memahami arsitektur membuat kalian tidak sekadar menghafal API, tapi tahu alasan di balik setiap perilaku — misalnya kenapa query di-cache, kenapa kolom didefinisikan sebagai data, dan kenapa router memisahkan state dari komponen.

Episode 2 membedah empat arsitektur inti: query client dan cache di TanStack Query, sistem kolom dan row model di TanStack Table, state management serta loader di TanStack Router, dan cara virtualizer mengukur viewport di TanStack Virtual.

Konsep ini adalah fondasi. Di episode 3 kalian akan menyentuh kode sungguhan, dan setiap detail arsitektur yang dipelajari di sini akan terpakai sampai episode 23.

Arsitektur TanStack Query di Balik Layar

QueryClient, QueryCache, dan QueryObserver

Inti TanStack Query adalah QueryClient yang menampung QueryCache. Setiap pemanggilan useQuery menciptakan sebuah Query di cache, dan komponen yang berlangganan disebut QueryObserver. Saat beberapa komponen memakai queryKey yang sama, mereka berbagi satu Query — inilah dasar deduplication.

JSQueryClient dengan default global
import { QueryClient } from "@tanstack/react-query"
 
const queryClient = new QueryClient({
  defaultOptions: {
    queries: { staleTime: 30_000, retry: 1 },
  },
})

new QueryClient({ defaultOptions }) mengatur perilaku default semua query. staleTime: 30_000 membuat data dianggap basi setelah 30 detik, dan retry: 1 membatasi percobaan ulang saat error. Keduanya akan dibahas detail di episode 4.

Alur Kerja Query

Ketika komponen me-mount, observer mengecek cache: jika ada data valid, langsung dipakai tanpa fetch. Jika tidak ada atau sudah stale, query di-fetch ulang di background. Setelah selesai, hasil ditulis ke cache dan semua observer yang berlangganan di-notifikasi. Pola ini menjelaskan kenapa pindah halaman terasa instan — data sudah hangat di cache.

Provider Context

QueryClientProvider menyalurkan queryClient ke seluruh pohon komponen lewat React context. Tanpa provider ini, useQuery tidak tahu cache mana yang dipakai dan langsung melempar error.

Arsitektur TanStack Table

Table Core dan Column Definitions

TanStack Table membagi dua hal: core table yang menangani state dan logika, serta rendering yang sepenuhnya kalian kontrol. Kolom didefinisikan sebagai data lewat columnHelper, sehingga kolom bisa dibuat dinamis, diturunkan, atau diprogram.

JSDefinisi kolom sebagai data
import { createColumnHelper } from "@tanstack/react-table"
 
const columnHelper = createColumnHelper()
 
const columns = [
  columnHelper.accessor("nama", { header: "Nama" }),
  columnHelper.accessor("tahun", { header: "Tahun" }),
]

columnHelper.accessor("nama", { header: "Nama" }) memetakan kolom ke properti nama dari data, dengan label header. Array columns ini yang nanti diteruskan ke useReactTable di episode 6.

Row Model

Row model adalah mesin yang mengolah data mentah menjadi baris yang siap dirender. getCoreRowModel adalah model dasar; di episode 6 dan 9 kalian akan menambahkan model sorting, filtering, grouping, dan pagination. Setiap model membungkus model sebelumnya dalam pipeline.

Arsitektur TanStack Router

Route Tree dan Router State

TanStack Router menyusun seluruh aplikasi sebagai route tree. Setiap route adalah objek dengan path, loader, dan component. Router memegang state terpusat — termasuk current location, search params, dan loader data — lalu me-notifikasi komponen saat berubah.

JSMembangun route tree
import { createRootRoute, createRoute, createRouter } from "@tanstack/react-router"
 
const rootRoute = createRootRoute()
const routeTree = rootRoute.addChildren([])
const router = createRouter({ routeTree })

createRouter({ routeTree }) menghasilkan router yang diteruskan ke RouterProvider. Seluruh tree route bersifat type-safe: URL yang salah ditolak compiler.

Loader dan Navigation Lifecycle

Saat navigasi terjadi, router memanggil loader dari route tujuan, menunggu datanya atau menampilkan pending state, lalu menampilkan komponen. Data hasil loader dibaca komponen lewat useLoaderData. Lifecycle ini membuat router tahu persis kapan harus menampilkan loading, sukses, atau error.

Arsitektur TanStack Virtual

Virtualizer dan Viewport Measurement

TanStack Virtual memakai Virtualizer untuk menentukan item mana yang terlihat dalam viewport. Virtualizer membaca posisi scroll lewat getScrollElement, menghitung rentang item yang terlihat, lalu memberi tahu berapa tinggi total area scroll.

JSVirtualizer untuk list raksasa
import { useVirtualizer } from "@tanstack/react-virtual"
 
const virtualizer = useVirtualizer({
  count: 10_000,
  getScrollElement: () => parentRef.current,
  estimateSize: () => 40,
})

count: 10_000 menyatakan jumlah item, dan estimateSize: () => 40 adalah estimasi tinggi awal tiap item. Hanya item yang terlihat yang di-render — sisanya digantikan blok kosong dengan ukuran yang sama.

Item Rendering

Setiap item virtual diberi start dan size. Komponen menempatkan item secara absolute menggunakan transformasi translateY sebesar nilai start. Hasilnya, scroll tetap mulus meskipun data berukuran jutaan baris — detail lengkapnya ada di episode 11.

Penutup

Episode 2 membedah arsitektur empat library inti: query client dan cache di Query, core table dan row model di Table, route tree dan lifecycle loader di Router, serta virtualizer dan viewport di Virtual. Semua arsitektur ini berbagi satu pola: logika dipisahkan dari rendering.

Inti yang harus dibawa pulang:

  • QueryClient menampung QueryCache; observer berlangganan ke query yang sama.
  • TanStack Table memisahkan core logic dari rendering yang kalian kontrol.
  • Router menyusun route tree dan memegang state terpusat.
  • Loader dipanggil saat navigasi dan hasilnya dibaca lewat useLoaderData.
  • Virtualizer hanya merender item yang ada dalam viewport.
  • Pemisahan logika dan rendering adalah benang merah seluruh TanStack.

Di episode 3 selanjutnya kita akan memulai proyek dengan TanStack — scaffold proyek Vite React-TypeScript, instalasi kelima library @tanstack/*, struktur folder, serta konfigurasi TypeScript dan ESLint. Siapkan terminal kalian, karena mulai episode 3 kita menulis kode sungguhan!