
Kalau lo baru mulai belajar jadi frontend developer, mungkin lo masih mikir kalau kerjaan utama lo cuma ngatur layout, warna tombol, bikin animasi, atau ngubah font supaya keliatan lebih estetik. Dan memang, itu bagian dari kerjaan lo. Tapi sebenarnya, tugas lo lebih dari sekadar bikin UI yang “cantik”. Lo tuh ibarat gerbang utama dari sebuah aplikasi—semua data dan fitur yang udah disiapin backend developer, ujung-ujungnya lewat lo yang nampilin ke user.
Kalau lo gagal nampilin data dengan cara yang efisien, cepet, dan mudah dipahami, user gak bakal peduli backend lo sekuat apa. Buat mereka, yang keliatan di layar itulah aplikasinya.
Nah, di sinilah peran penting lo sebagai frontend developer: lo harus consume data dari backend API, lalu tampilkan data itu dengan baik. Tapi bukan cuma “manggil API” doang ya. Lo juga harus mikirin banyak hal lain—misalnya, gimana ngatur loading state biar user gak kebingungan, gimana handle error kalau ada masalah saat ambil data, gimana biar data yang udah lo ambil bisa dipakai ulang di halaman lain tanpa fetch ulang, atau gimna caranya lo bisa trigger update data dengan efisien kalau user ngelakuin aksi tertentu (kayak submit form, delete item, dan sebagainya).
Kebayang gak tuh? Dari luar kelihatan simple, tapi di dalamnya banyak banget yang harus lo pikirin. Dan makin besar project lo, makin banyak data yang harus di-fetch, makin kompleks logic yang harus lo kelola. Apalagi kalau datanya saling bergantung satu sama lain.
Salah langkah sedikit, bisa bikin aplikasi lo jadi lambat, boros request, atau bahkan ngebug karena salah urus state. Di titik inilah lo akan sadar bahwa ngatur data di frontend itu gak semudah useEffect
+ useState
doang.
Apa yang Bakal Kita Pelajari di Artikel Ini
Nah, karena tantangan consume data dari backend itu ternyata lebih ribet dari kelihatannya, lo butuh tools yang bisa bantu lo ngelola semua itu dengan cara yang lebih rapi dan scalable. Dan di sinilah React Query (TanStack Query) hadir sebagai penyelamat. Tools ini secara khusus dibuat buat ngebantu frontend developer dalam hal pengambilan, penyimpanan, dan sinkronisasi data API tanpa harus ribet setup logic sendiri.
Di artikel ini, kita gak langsung loncat ke coding atau implementasi yang kompleks. Gue pengen ajak lo buat pelan-pelan kenalan dulu sama React Query. Gimana sih mindset dasarnya, kenapa tools ini penting banget buat lo pelajari sebagai pemula, dan kenapa banyak developer pro yang udah gak mau balik lagi ke cara manual setelah pakai React Query.
Tujuan utamanya sih sederhana—supaya lo bisa bikin aplikasi React yang lebih raapi, efisien, dan enak dipakai, tanpa harus psing ngatur state loading, error, atau cache secara manual. Karena pada akhirnya, frontend developer yang baik itu bukan cuma yang bisa bikin UI bagus, tapi juga bisa nyajikan data dengan cara yang benar, cepat, dan stabil.
Jadi lo gak cuma belajar tools baru, tapi juga belajar cara mikir yang lebih profesional dalam ngelola data di aplikasi React. Santai aja, kita bahasnya pelan-pelan. Siapin kopi dulu kalau perlu, karena abis ini kita bakal masuk ke manfaat dan contoh implementasinya langsung di React project lo.
10 Manfaat Menggunakan React Query TanStack (dibanding cara manual)
Setelah kita bahas pentingnya peran frontend developer dan kenapa React Query bisa jadi solusi buat ngatur data API, sekarang saatnya masuk ke bagian serunya: manfaat nyata ketika lo pakai React Query dibanding cara manual, lengkap dengan contoh kode real-world. Gue yakin, setelah lo lihat sendiri perbandingannya, lo bakal mikir, “kenapa gak dari dulu aja gue pake ini?”
Manfaat pertama: otomatis ngatuar loading state tanpa bikin state manual
Kalau lo gak pakai React Query, biasanya lo bikin useState
buat loading, terus atur logic true
dan false
di dalam useEffect
.
Contoh tanpa React Query:
import { useState, useEffect } from "react";
import axios from "axios";
const ProductList = () => {
const [products, setProducts] = useState([]);
const [loading, setLoading] = useState(true);
useEffect(() => {
axios.get("/api/products")
.then(res => setProducts(res.data))
.finally(() => setLoading(false));
}, []);
if (loading) return <p>Loading...</p>;
return (
<ul>
{products.map(product => <li key={product.id}>{product.name}</li>)}
</ul>
);
};
Sekarang bandingkan dengan React Query:
import { useQuery } from "@tanstack/react-query";
import axios from "axios";
const fetchProducts = () => axios.get("/api/products").then(res => res.data);
const ProductList = () => {
const { data, isPending } = useQuery({
queryKey: ["products"],
queryFn: fetchProducts,
});
if (isPending) return <p>Loading...</p>;
return (
<ul>
{data.map(product => <li key={product.id}>{product.name}</li>)}
</ul>
);
};
Lebih clean, gak ada useEffect
, gak ada useState
, tapi semua tetap jalan rapi.
Manfaat kedua: error handling lebih simpel dan konsisten
Kalau gak pakai React Query, biasanya lo handle error pakai try/catch
atau .catch()
lalu simpen error ke state.
Tanpa React Query:
const [error, setError] = useState(null);
useEffect(() => {
axios.get("/api/products")
.then(res => setProducts(res.data))
.catch(err => setError(err));
}, []);
if (error) return <p>Something went wrong: {error.message}</p>;
Dengan React Query:
const { data, isError, error } = useQuery({
queryKey: ["products"],
queryFn: fetchProducts,
});
if (isError) return <p>Error: {error.message}</p>;
Semuanya udah disediakan. Tinggal pakai.
Manfaat ketiga: auto refetch data saat kembali ke tab browser
React Query secara default akan refetch data saat user kembali ke halaman, jadi datanya selalu fresh.
Tanpa React Query:
useEffect(() => {
const handleFocus = () => {
axios.get("/api/products").then(res => setProducts(res.data));
};
window.addEventListener("focus", handleFocus);
return () => window.removeEventListener("focsus", handleFocus);
}, []);
Dengan React Query:
useQuery({
queryKey: ["products"],
queryFn: fetchProducts,
refetchOnWindowFocus: true, // default true
});
Cuma tinggal nyebut opsinya aja.
Manfaat keempat: caching otomatis dan smart
React Query otomatis nyimpen hasil fetch, jadi data bisa dipakai ulang di koomponen lain tanpa loading ulang.
Komponen A:
const { data: products } = useQuery({
queryKey: ["products"],
queryFn: fetchProducts,
});
Komponen B (di halaman lain):
const { data: products } = useQuery({
queryKey: ["products"],
queryFn: fetchProducts,
});
Kalau data udah pernah di-fetch sebelumnya, dia langsung tampil dari cache, gak loading ulang.
Manfaat kelima: kontrol waktu validitas data (staleTime)
Kadang kita pengen data dianggap fresh selama 5 menit. React Query bisa atur itu.
useQuery({
queryKey: ["products"],
queryFn: fetchProducts,
staleTime: 1000 * 60 * 5, // data dianggap fresh selama 5 menit
});
Kalau gak pakai React Query, lo harus bikin timer dan pengecekan manual sendiri.
Manfaat keenam: cancel request lama secara otomatis
Kalau user pindah halaman sebelum request selesai, React Query bakal otomatis cancel request tersebut.
Manual approach? Lo harus pakai AbortController
.
Tanpa React Query:
const controller = new AbortController();
useEffect(() => {
axios.get("/api/products", { signal: controller.signal })
.then(res => setProducts(res.data));
return () => controller.abort();
}, []);
Dengan React Query: cukup gunakan queryFn
seperti biasa, dia handle sendiri.
Manfaat ketujuh: mutation jaadi lebih rapi dengan hook useMutation
Misal lo mau submit form dan setelah itu refetch data.
Tanpa React Query:
const handleSubmit = () => {
axios.post("/api/products", newProduct)
.then(() => {
axios.get("/api/products").then(res => setProducts(res.data));
});
};
Dengan React Query:
import { useMutation, useQueryClient } from "@tanstack/react-query";
const queryClient = useQueryClient();
const mutation = useMutation({
mutationFn: (newProduct) => axios.post("/api/products", newProduct),
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ["products"] });
},
});
Data langsung fresh setelah berhasil submit.
Manfaat kedelapan: infinite scroll dan pagination jadi lebih gampang
React Query punya useInfiniteQuery
untuk bantu lo implementasi infinite scroll.
useInfiniteQuery({
queryKey: ["products"],
queryFn: ({ pageParam = 1 }) => fetch(`/api/products?page=${pageParam}`).then(res => res.json()),
getNextPageParam: (lastPage, pages) => lastPage.nextPage,
});
Kalau lo manual, lo harus simpen page number, track total data, handle load more state, dan logicnya bisa panjang banget.
Manfaat kesembilan: query invalidation otomatis setelah mutasi
Setelah lo update atau delete data, React Query bisa langsung re-fetch data terkait.
useMutation({
mutationFn: deleteProduct,
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ["products"] });
},
});
Tanpa ini, user bisa lihat data lama atau harus refresh page.
Manfaat kesepuluh: query logic bisa disimpan jadi custom hook
Biar lebih reusable, lo bisa bikin custom hook kayak useProducts
.
export const useProducts = () => {
return useQuery({
queryKey: ["products"],
queryFn: fetchProducts,
staleTime: 1000 * 60 * 5,
});
};
Jadi tinggal panggil useProducts()
di mana aja. Tanpa React Query, lo harus copy-paste logic useEffect
dan useState
di tiap komponen.
Cara Membuat Project React Terbaru Menggunakan Vite
Sebelum kita masuk ke dunia React Query, tentu kita harus punya dulu project React-nya. Dan sekarang, cara paling modern dan cepat untuk bikin project React adalah pakai Vite. Tools ini ringan, cepat banget waktu start-nya, dan udah jadi standar baru untuk banyak developer frontend.
Langkah pertama, pastikan lo udah install Node.js versi terbaru. Cek lewat terminal:
node -v
Kalau udah, lo bisa langsung jalankan perintah berikut buat bikin project React dengan Vite:
npm create vite@latest my-react-query-app -- --template react
Perintah ini bakal bikin folder my-react-query-app
dengan template React bawaan dari Vite.
Setelah itu, masuk ke folder project dan install dependency-nya:
cd my-react-query-app
npm install
Kalau lo pakai TypeScript, bisa ganti template --template react
jadi --template react-ts
.
Setelah semuanya terpasang, jalankan development server-nya dengan:
npm run dev
Nanti lo bisa buka browser dan akses http://localhost:5173
. Kalau tampilannya muncul tulisan “Vite + React”, berarti project lo udah berhasil dibuat dan siap dipakai.
Cara Menambahkan React Query TanStack ke Project Vite React
Sekarang, setelah project-nya jadi, saatnya kita tambahkan React Query ke dalam project ini. React Query itu paket resmi dari TanStack, dan cara install-nya sangat gampang.
Di terminal, jalankan perintah berikut:
npm install @tanstack/react-query
Setelah berhasil, lo juga bisa tambahkan devtools-nya biar gampang ngecek status query saat ngembangin aplikasi:
npm install @tanstack/react-query-devtools
Langkah berikutnya adalah setup provider React Query di root aplikasi. Buka file main.jsx
dan ubah isinya jadi seperti ini:
import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App.jsx';
import './index.css';
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
const queryClient = new QueryClient();
ReactDOM.createRoot(document.getElementById('root')).render(
<React.StrictMode>
<QueryClientProvider client={queryClient}>
<App />
</QueryClientProvider>
</React.StrictMode>,
);
Dengan ini, lo udah siap pakai semua fitur React Query di seluruh aplikasi lo.
Sekarang mari kita coba implementasi sederhana buat fetch data. Misalnya kita mau ambil data users dari placeholder API.
Pertama, buka App.jsx
dan ubah jadi seperti ini:
import { useQuery } from '@tanstack/react-query';
import axios from 'axios';
const fetchUsers = async () => {
const response = await axios.get('<https://jsonplaceholder.typicode.com/users>');
return response.data;
};
function App() {
const { data, isPending, isError, error } = useQuery({
queryKey: ['users'],
queryFn: fetchUsers,
});
if (isPending) {
return <p>Loading data...</p>;
}
if (isError) {
return <p>Error occurred: {error.message}</p>;
}
return (
<div>
<h1>Daftar Pengguna</h1>
<ul>
{data.map((user) => (
<li key={user.id}>
{user.name} — {user.email}
</li>
))}
</ul>
</div>
);
}
export default App;
Dalam contoh di atas, lo bisa lihat bahwa kita gak prerlu bikin useState
, useEffect
, atau handle loading dan error state manual. Semuanya udah ditangani dengan rapi oleh React Query.
Kalau lo juga install devtoolsa-nya tadi, lo bisa tambahkan satu baris di bawah <App />
buat bantu debugging:
import { ReactQueryDevtools } from '@tanstack/react-query-devtools';
// Di dalam render:
<QueryClientProvider client={queryClient}>
<App />
<ReactQueryDevtools initialIsOpen={false} />
</QueryClientProvider>
Dengan ini, lo bisa lihat status dari semua query yang lo buhat di aplikasi, termasuk apakah sedang loading, sukses, error, dan kapan terakhir kali data di-fetch.
Sekarang lo udah punya project React modern dengan Vite, dan udah terpasang React Query lengkap dengan devtools. Ke depan, semua data fetching lo bakal jauh lebih clean, powerful, dan gampang dikelola — tinggal fokus ke logic aplikasinya, bukan mikirin boilerplate terus.
Jika Tanppa Pake React Query
Sekarang gue tunjukin versi tanpa menggunakan React Query, supaya lo bisa langsung bandingin effort dan kompleksitaasnya dengan versi yang pakai React Query tadi.
Contoh ini akan ambil data dari https://jsonplaceholder.typicode.com/users
dan nampilin daftar nama + email pengguna, sama seperti versi sebelumnya — tapi ditulis full manual pakai useState
dan useEffect
.
import { useEffect, useState } from 'react';
import axios from 'axios';
function App() {
const [users, setUsers] = useState([]);
const [loading, setLoading] = useState(true);
const [error, setError] = useState(null);
useEffect(() => {
const fetchUsers = async () => {
try {
setLoading(true); // mulai loading
const response = await axios.get('<https://jsonplaceholder.typicode.com/users>');
setUsers(response.data); // simpan data
} catch (err) {
setError(err); // simpan error jika ada
} finally {
setLoading(false); // selesai loading
}
};
fetchUsers();
}, []);
if (loading) {
return <p>Loading data...</p>;
}
if (error) {
return <p>Terjadi kesalahan: {error.message}</p>;
}
return (
<div>
<h1>Daftar Pengguna</h1>
<ul>
{users.map((user) => (
<li key={user.id}>
{user.name} — {user.email}
</li>
))}
</ul>
</div>
);
}
export default App;
Penjelasan singkatnya:
- Kita harus bikin
useState
tiga kali: satu buat data, satu buat loading, satu lagi buat error. - Di
useEffect
, kita bikin fungsi async manaual buat nge-fetch data. - Harus handle
try
,catch
, danfinally
sendiri untuk kelola state dengan benar. - Gak ada caching, gak ada invalidation otomatis, gak ada refetch on window focus, semua harus diatur manual kalau dibutuhkan.
Dengan contoh ini lo bisa ngerasain sendiri bedanya: React Query bikin semua logic itu jadi lebih pendek, bersih, dan bisa di-scale ke banyak tempat. Tapi di sisi lain, penting juga paham cara manual kayak gini, karena ini jadi dasar buat ngerti kenapa kita butuh abstraction seperti React Query.
5 Contoh Analogi React Query TanStack di Dunia Restoran (Plus Kode Nyatanya)
Biar konsep React Query makin nempel di kepala, kita coba bandingkan dengan sesuatu yang lebih akrab: dunia restoran. Kenapa restoran? Karena alur kerja di restoran ternyata mirip banget sama alur ambil data di aplikasi—ada dapur (backend), ada pelayan (frontend), ada pelanggan (user), dan ada alur penyajian makanan (data). Kita bahas satu per satu ya, santai aja.
Analogi pertama: caching seperti pelanggan tetap yang punya pesanan langganan
Bayangin lo sering banget datang ke restoran yang sama, dan setiap kali lo datang, lo selalu pesen nasi goreng. Nah, pelayannya udah hafal sama kebiasaan lo, jadi dia gak perlu nanya ulang pesanan lo tiap kali lo datang. Itulah konsep caching di React Query.
Kode tanpa React Query:
useEffect(() => {
axios.get('/api/nasi-goreng').then((res) => setData(res.data));
}, []);
Tiap buka halaman, dia fetch lagi walau datanya sama.
Kode dengan React Query:
const { data } = useQuery({
queryKey: ['nasi-goreng'],
queryFn: () => axios.get('/api/nasi-goreng').then(res => res.data),
});
React Query otomatis simpan hasil fetch di cache. Jadi kalau lo buka halaman lain dan balik lagi, datanya langsung muncul tanpa harus fetch ulang.
Analogi kedua: loading state seperti pelayan bilang "makanan sedang disiapkan ya, ditunggu sebentar"
Waktu lo pesen makanan di restoran, lo gak langsung dapet makanannya kan? Tapi pelayan biasanya ngasih tahu statusnya: “mohon tungagu, sedang dimasak.” Itu sama dengan isPending
atau isLoading
di React Query.
Tanpa React Query:
const [loading, setLoading] = useState(true);
useEffect(() => {
axios.get('/api/makanan').then(() => {
setLoading(false);
});
}, []);
Harus atur manual kapan loading selesai.
Dengan React Query:
const { isPending } = useQuery({
queryKey: ['makanan'],
queryFn: () => axios.get('/api/makanan').then(res => res.data),
});
Langsung dapet status loading tanpa bikin state sendiri.
Analogi ketiga: refetch otomatis saat pelanggan nanya "mas, makanannya udah jadi belum?"
Kadang pelanggan itu gak sabaran dan nanya ke pelayan lagi buat mastiin makanannya udah selesai atau belum. Nah, ini mirip kayak refetchOnWindowFocus
di React Query. Kalau user balik lagi ke halaman (misalnya habis pindah tab), React Query akan otomatis nanya ulang ke server apakah datanya udah update.
Tanpa React Query, harus bikin event listener sendiri:
useEffect(() => {
const onFocus = () => {
axios.get('/api/menu').then(res => setMenu(res.data));
};
window.addEventListener('focus', onFocus);
return () => window.removeEventListener('focus', onFocus);
}, []);
Dengan React Query:
useQuery({
queryKey: ['menu'],
queryFn: () => axios.get('/api/menu').then(res => res.data),
refetchOnWindowFocus: true,
});
React Query udah otomatis handle ini di balik layar. Gak perlu ribet.
Analogi keempat: mutasi seperti pelanggan memesan makanan baru dan dapurnya langsung update
Kalau pelanggan pesen makanan baru, dapurnya langsung proses dan pelayan update statusnya. Ini mirip banget dengan useMutation
di React Query.
Tanpa React Query:
const addMenu = (newMenu) => {
axios.post('/api/menu', newMenu).then(() => {
axios.get('/api/menu').then(res => setMenu(res.data));
});
};
Dengan React Query:
const queryClient = useQueryClient();
const { mutate } = useMutation({
mutationFn: (newMenu) => axios.post('/api/menu', newMenu),
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ['menu'] });
},
});
Langsung refetch menu terbaru setelah mutasi sukses. Kayak pelayan langsung ngecek ulang ke dapur.
Analogi kelima: devtools seperti kamera CCTV di dapur yang bisa liat proses masaknya
Restoran profesional biasanya punya dapur terbuka atau CCTV buat mantau proses masak biar tahu kalau ada masalah. Nah, React Query juga punya Devtools yang kasih lo visual semua query yang jalan, statusnya, apakah error, loading, atau udah sukses.
Setup-nya super gampang:
import { ReactQueryDevtools } from '@tanstack/react-query-devtools';
<QueryClientProvider client={queryClient}>
<App />
<ReactQueryDevtools initialIsOpen={false} />
</QueryClientProvider>
Kalau lo buka aplikasi, Devtools ini akan nunjukin query yang aktif, hasilnya, dan semua history fetch. Sangat berguna buat debugging atau lihat performa aplikasi real-time.
Jadi kalau ditarik benang merahnya, React Query itu kayak sistem restoran modern. Dia hafal pelanggan (caching), kasih info status pesanan (loading), nanyain ulang secara berkala (refetch), langsung respon kalau ada pesanan baru (mutation), dan kasih visualisasi ke dapur (devtools). Gak heran kenapa React Query bikin kerjaan lo jauh lebih gampang dan profesional.
5 Kesalahan Umum Pemula Saat Awal Pakai React Query (dan Solusi Lengkapnya)
Gue paham banget, pas pertama kali nyobain React Query, rasanya kayak "wah enak banget ya tinggal pakai hook buat ambil data", tapi ternyata... gak semudah itu juga. Karena meskipun React Query itu powerful, tetap aja banyak pemula yang sering kejebak kesalahan kecil yang bikin datanya gak muncul, loading gak kelar, atau bahkan malah error terus.
Tenang bro, di bawah ini gue bakal kasih 5 contoh kesalahan paling sering terjadi saat pemula pakai React Query, lengkap sama solusi dan contoh kode real-nya. Biar lo gak perlu ngalamin sakit kepala yang sama.
Kesalahan pertama: lupa bungkus aplikasi dengan QueryClientProvider
Ini adalah kesalahan yang paling sering kejadian. Lo langsung pakai useQuery
di komponen, tapi lupa bahwa QueryClientProvider
itu wajib banget ada di root aplikasi.
Contoh yang salah:
import { useQuery } from '@tanstack/react-query';
function App() {
const { data } = useQuery({
queryKey: ['users'],
queryFn: () => axios.get('/api/users').then(res => res.data),
});
return <div>{JSON.stringify(data)}</div>;
}
export default App;
Kalau lo jalanin, ini bakal error karena React Query belum dikasih "klien" untuk jalanin hook-nya.
Solusi:
import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App.jsx';
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
const queryClient = new QueryClient();
ReactDOM.createRoot(document.getElementById('root')).render(
<React.StrictMode>
<QueryClientProvider client={queryClient}>
<App />
</QueryClientProvider>
</React.StrictMode>
);
Baru setelah itu lo bisa pakai useQuery
di komponen mana pun.
Kesalahan kedua: queryKey tidak konsisten atau tidak unik
Banyak pemula nulis queryKey
sembarangan, misalnya pakai string doang tanpa kombinasi parameter. Akibatnya, cache-nya bentrok atau query-nya gak ke-trigger ulang ketika seharusnya dia refetch.
Contoh salah:
const { data } = useQuery({
queryKey: ['product'],
queryFn: () => axios.get(`/api/product/${id}`).then(res => res.data),
});
Kalau id
berubah, data gak refetch karena queryKey
gak berubah.
Solusi:
const { data } = useQuery({
queryKey: ['product', id],
queryFn: () => axios.get(`/api/product/${id}`).then(res => res.data),
});
Dengan begini, React Query tahu kalau id
berubah, dia harus ambil data baru.
Kesalahan ketiga: langsung pakai data.map()
padahal data
masih undefined
Kadang lo terlalu semangat langsung render data.map()
padahal data-nya belum dateng. Ini bikin error di render: Cannot read properties of undefined (reading 'map').
Contoh yang salah:
const { data } = useQuery({
queryKey: ['users'],
queryFn: fetchUsers,
});
return (
<ul>
{data.map(user => <li key={user.id}>{user.name}</li>)}
</ul>
);
Solusinya, pastikan lo cek dulu apakah data
udah ada:
if (!data) return <p>Loading...</p>;
return (
<ul>
{data.map(user => <li key={user.id}>{user.name}</li>)}
</ul>
);
Atau lo juga bisa pakai isPending
:
const { data, isPending } = useQuery({
queryKey: ['users'],
queryFn: fetchUsers,
});
if (isPending) return <p>Loading...</p>;
Kesalahan keempat: pakai async di queryFn
tapi lupa return data-nya
Lo nulis fungsi async, tapi lupa return
hasilnya. Akibatnya, React Query gak nerima data apapun.
Contoh salah:
const fetchUsers = async () => {
axios.get('/api/users'); // lupa return
};
useQuery({
queryKey: ['users'],
queryFn: fetchUsers,
});
Solusi:
const fetchUsers = async () => {
const res = await axios.get('/api/users');
return res.data;
};
React Query butuh return dari queryFn
buat nge-cache dan render datanya.
Kesalahan kelima: lupa handle error state, bikin user bingung saat API gagal
Banyak pemula cuma handle loading dan success, tapi gak kasih fallback pas data gagal di-fetch. User jadi diem aja ngeliat layar kosong, gak tahu kenapa.
Contoh yang kurang lengkap:
const { data, isPending } = useQuery({
queryKey: ['users'],
queryFn: fetchUsers,
});
if (isPending) return <p>Loading...</p>;
// kalau error, gak ada apa-apa di layar
Solusi:
const { data, isPending, isError, error } = useQuery({
queryKey: ['users'],
queryFn: fetchUsers,
});
if (isPending) return <p>Loading...</p>;
if (isError) return <p>Error: {error.message}</p>;
return (
<ul>
{data.map(user => <li key={user.id}>{user.name}</li>)}
</ul>
);
Dengan isError
, lo bisa kasih feedback jelas ke user. Apalagi kalau project-nya production, penting banget transparan soal error.
Kesimpulannya, React Query itu powerful banget, tapi juga butuh disiplin kecil dari kita sebagai developer buat gunain dengan benar. Kesalahan kecil kayak lupa return, queryKey gak rapi, atau lupa handle error, bisa bikin aplikasi lo gak maksimal.
Tapi setelah paham logika dasarnya, semuanya jadi jauh lebih mudah. Yang penting: jangan buru-buru, pahami dulu alurnya, dan biasakan testing tiap kondisi dengan baik.
Saran Buat Kamu yang Baru Mulai Jadi Web Developer
Kalau lo baru masuk ke dunia web development, apalagi kalau fokusnya ke React, gue ngerti banget rasanya. Banyak hal yang harus dipelajari: dari dasar-dasar komponen, state, hingga cara kerja fetching data, dan semua itu bisa bikin lo bingung harus mulai dari mana.
Apalagi kalau lo pengen serius dan punya target kerja remote, bersaing di pasar global, atau bahkan punya portofolio keren yang bisa dikirim ke klien luar negeri.
Makanya, gue saranin banget buat ikut kelas React dari mentor expert di BuildWithAngga. Kelas ini bukan sekadar kumpulan video tutorial, tapi disusun langsung oleh mentor yang udah punya pengalaman kerja nyata — bahkan beberapa dari mereka udah bantu banyak student buat dapat kerja remote dan proyek global.
Kelebihan dari kelas ini juga gak main-main:
- Portofolio berkualitas tinggi: lo bakal bangun project beneran, bukan cuma todo list. Project-nya realistis, punya tampilan profesional, dan bisa lo pajang langsung di CV atau LinkedIn lo buat narik perhatian recruiter.
- Akses kelas selamanya: lo gak perlu khawatir kejar-kejaran waktu. Mau belajar pagi, malam, atau pas weekend aja juga bisa. Cocok buat lo yang mungkin masih kuliah, kerja, atau punya kesibukan lain.
- Forum diskusi bareng mentor: ini salah satu fitur paling powerful. Lo bisa langsung tanya ke mentor kalau mentok, atau diskusi bareng temen-temen lain yang juga lagi belajar. Jadi lo gak akan merasa belajar sendirian.
Kalau lo memang punya mimpi untuk jadi web developer profesional, kerja remote dari mana aja, dan bikin aplikasi yang keren dan beneran dipakai orang, gue yakin investasi waktu dan tenaga di kelas ini bakal jadi langkah awal yang sangat tepat.
Jangan cuma puas bisa React. Kuasai mindset-nya, kuasai praktiknya, dan bangun portofolio yang bisa nunjukin skill lo. Kelas React di BuildWithAngga bisa bantu lo ke sana.