Mengenal Tanstack-Query pada Frontend Web Development

Daffa Aldzakian Fauzi
TLabCircle
Published in
4 min readDec 28, 2023

Sebagian besar pengembangan frontend web development tidak dilengkapi dengan cara mengambil atau memperbarui data secara pasti. Setiap developer memiliki metodenya masing-masing. Oleh karena itu, developer akhirnya membuat boilerplate atau standarisasinya sendiri dalam mengambil data. Hal ini biasanya menggabungkan custom state based-on-component dan side-effect-nya, atau menggunakan state management yang lebih umum untuk menyimpan dan menyediakan data asynchronous di seluruh aplikasinya.

Tapi hal tersebut belum lah efektif dikarenakan metode/standarisasi yang dimiliki setiap developer kemungkinan berbeda, ini juga berdampak kepada lamanya masa transfer knowledge yang dibutuhkan apabila aplikasi tersebut membutuhkan developer baru untuk di-maintenance.

Kita sebagai developer sebagian besar mengandalkan library seperti Axios untuk menangani request terhadap server, tetapi setelah itu kita bergantung pada aplikasi kita sendiri dalam menangani cara memproses data tersebut. Belum ada standar untuk proses selain request, seperti caching, sinkronisasi dan updating server state, dll.

Photo by Negative Space from Pexels: https://www.pexels.com/photo/coffee-writing-computer-blogging-34600/

React Query (Tanstack Query) adalah salah satu library yang recommended untuk mengelola server status. Ia bekerja dengan sangat baik, tanpa konfigurasi, dan dapat disesuaikan sesuai keinginanmu seiring dengan pertumbuhan aplikasi. React Query (Tanstack Query) memungkinkan untuk mengatasi kerumitan dari server status seperti: isFetching; isUpdating, dll. dan mengontrol data aplikasi sebelum data tersebut dapat di-consume.

kalau berbicara teknis, React Query memungkinkan kita untuk melakukan:

  • Membantu dalam menghapus banyak baris kode yang rumit dari aplikasi dan menggantinya hanya dengan beberapa baris logic React Query.
  • Menjadikan aplikasi menjadi lebih mudah untuk dipelihara dan lebih mudah dalam membangun fitur baru tanpa perlu khawatir memasang data-source server status baru
  • Memberikan dampak langsung pada end-user dengan membuat aplikasi terasa lebih cepat dan responsif dibandingkan sebelumnya.
  • Berpotensi membantu client/end-user dalam menghemat bandwidth dan meningkatkan kinerja memori

useQuery() dan useMutation()

Proses Instalasi

Pertama, install react-query pada project.

npm i react-query

Wrap aplikasi dengan komponen <QueryClientProvider>

import {
useQuery,
useMutation,
useQueryClient,
QueryClient,
QueryClientProvider,
} from '@tanstack/react-query'
import { getTodos, postTodo } from '@/app/(client)/hooks/api.ts'

// Membuat client
const queryClient = new QueryClient()

function App() {
return (
// Provide Client dengan Wrapping App-nya
<QueryClientProvider client={queryClient}>
<Todos />
</QueryClientProvider>
)
}

const Todos = () => {
const queryClient = useQueryClient()

// Queries
const query = useQuery({ queryKey: ['todos'], queryFn: getTodos })

// Mutations
const mutation = useMutation({
mutationFn: postTodo,
onSuccess: () => {
// Invalidate dan refetch
queryClient.invalidateQueries({ queryKey: ['todos'] })
},
})

return (
<div>
<ul>
{query.data?.map((todo) => (
<li key={todo.id}>{todo.title}</li>
))}
</ul>

<button
onClick={() => {
mutation.mutate({
id: Date.now(),
title: 'Do Laundry',
})
}}
isLoading={mutation.isLoading}
>
Add Todo
</button>
</div>
)
}
  • useQuery: biasa digunakan untuk method GET
  • useMutation: biasa digunakan untuk mutation data (PUT, POST, DELETE)

Destructuring: Variable paling berguna

Ada beberapa variable yang paling sering digunakan oleh developer khususnya dalam memanipulasi data, antara lain: data, isLoading, isError, ataupun yang lainnya.

Teknik diatas tetap dapat digunakan apabila dalam satu komponen hanya membutuhkan satu function saja. tapi apa yang bisa kita lakukan jika terdapat banyak request/response yang harus di-consume? maka kita dapat men-destructure variable-nya

import Loading from '@/app/components/ui/Loading'

const Todos = () => {
const queryClient = useQueryClient()

// Queries
const { data: myTodo, isLoading: isLoadingMyTodo } = useQuery({ queryKey: ['todos'], queryFn: getTodos })

// Mutations
const { mutate: addTodo, isLoading: isLoadingAddTodo, isError: isErrorAddTodo } = useMutation({
mutationFn: postTodo,
onSuccess: () => {
// Invalidate dan refetch
queryClient.invalidateQueries({ queryKey: ['todos'] })
},
onError: (err) => {
console.error(err)
}
})

if (isLoadingMyTodo) return <Loading />

return (
<div>
<ul>
{myTodo.data?.map((todo) => (
<li key={todo.id}>{todo.title}</li>
))}
</ul>

<button
onClick={() => {
addTodo({
id: Date.now(),
title: 'Do Laundry',
})
}}
isLoading={isLoadingAddTodo}
>
Add Todo
</button>
</div>
)
}

Kesimpulan

Mari kita lihat apa yang telah dicapai pada useQuery() dan useMutation():

  • Pengambilan Data yang Disederhanakan: menyederhanakan proses pengambilan data dari API dengan menyediakan cara deklaratif dan intuitif untuk menentukan query-nya. Ini mengabstraksi sebagian besar code boilerplate yang diperlukan untuk menangani pengambilan data.
  • Status Kesalahan dan Pemuatan: hook ini mengelola status loading dan error untuk aplikasimu. Ini memberikan indikator pemuatan saat data diambil, error handling, dan retry load data. Hal ini menyederhanakan logic UI, membuatnya lebih mudah untuk menampilkan komponen spinner pada saat loading atau pesan error tanpa penanganan variable/ref status secara manual.
  • Abstraksi Library API: dengan menggunakan useQuery(), kita dapat mengabstraksikan detail implementasi library API tertentu. Hal ini memungkinkan kita untuk beralih di antara pustaka API yang berbeda tanpa membuat perubahan signifikan pada codebase-mu, sehingga meningkatkan modularitas dan kemudahan pada saat maintenance kode tersebut.

Sumber

--

--