Belajar TanStack - Best Practices & Observability
Episode 14 of 24

Belajar TanStack - Best Practices & Observability

Episode ini membangun kebiasaan debugging: logging lifecycle query lewat QueryCache, memantau render cost, debugging TanStack Query dan Router dengan DevTools, serta instrumentation untuk menjaga aplikasi tetap sehat.

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

Pendahuluan

Setiap aplikasi akan bermasalah suatu saat: query yang tidak pernah refetch, komponen yang re-render tanpa alasan, atau navigasi yang lambat. Best practices dan observability menentukan seberapa cepat kalian menemukan akar masalahnya.

Episode 14 membahas logging query lifecycle, monitoring render cost, debugging dengan DevTools Query dan Router, serta instrumentation yang menjaga aplikasi tetap terukur.

Rutinitas observasi ini akan menghemat waktu berjam-jam. Setiap query yang aneh atau render yang boros bisa langsung diidentifikasi, bukan ditebak-tebak.

Logging Query Lifecycle Events

Callback Global di QueryCache

QueryCache menerima callback untuk seluruh siklus hidup query — satu tempat untuk logging tanpa menyentuh tiap useQuery:

JSQueryCache dengan callback global
import { QueryCache, QueryClient } from "@tanstack/react-query"
 
const queryCache = new QueryCache({
  onError: (error, query) => {
    console.error("Query gagal:", query.queryKey, error.message)
  },
  onSuccess: (data, query) => {
    console.info("Query sukses:", query.queryKey)
  },
  onSettled: (data, error, query) => {
    console.debug("Query selesai:", query.queryKey)
  },
})
 
const queryClient = new QueryClient({ queryCache })

onError, onSuccess, dan onSettled dipanggil untuk setiap query di aplikasi. Di development, log ini menunjukkan pola aneh — misalnya query yang gagal terus karena queryKey salah. Di production, callback yang sama bisa diteruskan ke service error reporting.

Monitoring Cache Performance dan Render Cost

Deteksi Render yang Boros

Render ulang yang berlebihan adalah musuh performa. Beberapa indikator yang patut dicurigai:

  • Komponen memanggil useQuery dengan queryFn yang membuat fungsi baru setiap render.
  • Inline object di options yang tidak di-memoize.
  • Tabel besar yang tidak memakai virtualisasi.

React DevTools Profiler menunjukkan durasi render tiap komponen. Kombinasi dengan best practice Query — queryKey dan queryFn yang stabil — biasanya cukup meredam render boros:

JSMenstabilkan queryKey dan queryFn
const queryKey = ["pengguna", filter] as const
 
const { data } = useQuery({
  queryKey,
  queryFn: ambilPengguna,
})

queryKey di-declare di luar atau di-memoize, dan queryFn merujuk fungsi stabil. TanStack Query membandingkan queryKey secara dalam; objek baru yang identik bisa memicu perilaku aneh. Fungsi stabil juga menjaga observer tidak dibuat ulang.

Debugging TanStack Query dan Router

React Query DevTools

DevTools Query menampilkan semua query beserta status, data cache, dan aksi manual:

JSDevtools hanya di development
const isDev = import.meta.env.DEV
 
<QueryClientProvider client={queryClient}>
  <App />
  {isDev && <ReactQueryDevtools initialIsOpen={false} />}
</QueryClientProvider>

import.meta.env.DEV bernilai true hanya saat development. Menjaga DevTools keluar dari bundle produksi mengurangi ukuran file dan risiko bocornya detail data internal.

TanStack Router DevTools

Router juga punya devtools untuk inspeksi route, loader, dan pencarian:

JSTanStack Router Devtools
import { TanStackRouterDevtools } from "@tanstack/router-devtools"
 
<RouterProvider router={router} />
{isDev && <TanStackRouterDevtools router={router} position="bottom-right" />}

<TanStackRouterDevtools /> menampilkan struktur route, data loader, dan memungkinkan simulasi navigasi. Dari panel ini, kalian bisa melihat loader mana yang belum selesai dan kenapa.

Menggunakan DevTools dan Instrumentation

Dari Development ke Production

DevTools membantu saat development; di production, gantikan dengan instrumentation ringan. Kirim error query ke layanan pelacak dan ukur latensi:

JSInstrumentasi ke layanan error tracking
const queryCache = new QueryCache({
  onError: (error, query) => {
    reportError(error, { context: { queryKey: query.queryKey } })
  },
})

reportError(error, { context }) meneruskan error query beserta konteks queryKey ke layanan seperti Sentry. Di episode 21, instrumentation ini diperluas menjadi observability penuh dengan metrik cache dan performa.

Tip

Biasakan menyimpan queryKey sebagai konstanta di satu file, misalnya lib/query-keys.ts. Selain konsisten, ini memudahkan debugging karena nama key terpusat dan bisa dicari.

Penutup

Episode 14 menutup observability: logging lifecycle lewat callback QueryCache, monitoring render cost dengan Profiler dan queryKey stabil, debugging dengan DevTools Query dan Router, serta instrumentation yang menyalurkan error ke layanan tracking.

Inti yang harus dibawa pulang:

  • Callback di QueryCache melacak seluruh lifecycle query dari satu titik.
  • QueryKey dan queryFn yang stabil mencegah render dan refetch boros.
  • React Query DevTools menampilkan status dan cache setiap query.
  • Router DevTools menginspeksi route, loader, dan navigasi.
  • DevTools sebaiknya hanya aktif di development.
  • Instrumentasi produksi menggantikan DevTools untuk observasi nyata.

Di episode 15 selanjutnya kita akan membahas full application patterns — membangun dashboard dengan TanStack Table dan Charts, mengoordinasikan query state, table state, dan router state, complex UI flows dengan nested routing, serta data-driven UI dan composition. Semua library TanStack akhirnya bekerja sama!

Belajar TanStack - Best Practices & Observability | Belajar TanStack