Belajar ReactJS - Data Fetching & Asynchronous UI
Episode 8 of 24

Belajar ReactJS - Data Fetching & Asynchronous UI

Episode ini mengajarkan fetching data dengan fetch, axios, dan async/await, plus pengelolaan loading state, error handling, dan normalisasi data. Kalian juga melihat pola Suspense yang stabil serta caching data memakai React Query atau SWR.

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

Pendahuluan

Aplikasi React yang berguna harus mengambil data dari server. Episode 8 membahas semua pola yang dibutuhkan: cara mengambil data dengan fetch dan axios, menulis alur async dengan async/await, serta mengelola tiga keadaan yang selalu ada — loading, error, dan sukses.

Di paruh kedua kita melihat pola yang lebih maju: Suspense untuk deklarasi loading, dan React Query / SWR untuk caching, retry, dan background refetch. Di sinilah aplikasi kalian benar-benar berkomunikasi dengan dunia luar secara efisien.

Fetching Data dengan fetch dan async/await

Fetch Dasar di useEffect

Pola paling dasar memakai fetch di dalam useEffect:

JSFetch data dengan useEffect
import { useEffect, useState } from "react"
 
function DaftarUser() {
  const [users, setUsers] = useState([])
  const [loading, setLoading] = useState(true)
  const [error, setError] = useState(null)
 
  useEffect(() => {
    fetch("https://jsonplaceholder.typicode.com/users")
      .then((res) => res.json())
      .then((data) => { setUsers(data); setLoading(false) })
      .catch((err) => { setError(err.message); setLoading(false) })
  }, [])
 
  if (loading) return <p>Memuat data...</p>
  if (error) return <p>Gagal: {error}</p>
  return <ul>{users.map((u) => <li key={u.id}>{u.name}</li>)}</ul>
}

fetch("https://jsonplaceholder.typicode.com/users").then((res) => res.json()) mengirim request lalu mengubah respons menjadi JSON. Tiga state (users, loading, error) menjaga UI tetap terinformasi di setiap tahap.

Versi async/await yang Lebih Rapi

Pola di atas bisa ditulis lebih bersih dengan async/await:

JSFetch dengan async/await
useEffect(() => {
  const ambilData = async () => {
    try {
      const res = await fetch("https://jsonplaceholder.typicode.com/users")
      if (!res.ok) throw new Error(`HTTP ${res.status}`)
      const data = await res.json()
      setUsers(data)
    } catch (e) {
      setError(e.message)
    } finally {
      setLoading(false)
    }
  }
  ambilData()
}, [])

const res = await fetch(url) menunggu respons, lalu if (!res.ok) throw new Error(...) melempar error untuk status HTTP non-2xx yang tidak otomatis gagal di fetch. Jangan lupa cek res.ok — ini sering dilupakan.

Menggunakan Axios

Axios adalah alternatif populer dengan interceptor dan penanganan error yang lebih nyaman:

Install axios
npm install axios
JSFetch dengan axios
import axios from "axios"
 
const res = await axios.get("https://jsonplaceholder.typicode.com/users")
setUsers(res.data)

axios.get(url) langsung melempar error untuk status 4xx/5xx, dan data berada di res.data. Untuk proyek dengan banyak endpoint, axios sering menjadi pilihan karena konfigurasi default yang mudah.

Loading State, Error Handling, dan Normalisasi Data

Membedakan Tiga Kondisi

Rancang UI untuk tiga kondisi secara eksplisit: loading (spinner atau skeleton), error (pesan + tombol coba lagi), dan sukses (data). Pola sederhananya:

JSPattern tiga kondisi
if (loading) return <Spinner />
if (error) return <PesanError pesan={error} onRetry={ambilData} />
return <Daftar data={data} />

Normalisasi Data

Data dari API sering tidak sesuai bentuk yang dipakai UI. Normalisasi mengubahnya menjadi bentuk yang nyaman: misalnya menyimpan array dari server ke sebuah Map berisi object per ID, memudahkan pencarian dan update. Lakukan normalisasi di satu tempat (custom hook atau layer data) agar komponen tidak perlu tahu format asli API.

Suspense dan Concurrent Data Fetching

Suspense untuk Menyatakan Loading

Suspense adalah mekanisme React untuk menunda rendering sampai data tersedia. Di React modern, kalian bisa membungkus komponen yang bergantung pada data dengan boundary Suspense:

JSSuspense boundary
import { Suspense } from "react"
 
function App() {
  return (
    <Suspense fallback={<p>Memuat profil...</p>}>
      <ProfilUser userId={1} />
    </Suspense>
  )
}

<Suspense fallback={<p>Memuat profil...</p>}>{:javascript}</Suspense> menampilkan fallback sementara komponen di dalamnya belum siap. Suspense membuat kode loading bersifat deklaratif, bukan tersebar di tiap komponen.

Pola Stabil vs Eksperimental

Suspense untuk code splitting sudah stabil lama (episode 9). Untuk data fetching, gunakan pola stabil yang tersedia hari ini — React Query atau SWR — karena suspending data fetching penuh baru matur di ekosistem server components (episode 23).

Caching Data dengan React Query atau SWR

React Query (TanStack Query)

Menulis fetching manual berarti menulis ulang retry, cache, dan refetch untuk tiap fitur. React Query menyederhanakan semuanya:

Install TanStack Query
npm install @tanstack/react-query
JSHook useQuery
import { useQuery } from "@tanstack/react-query"
 
function DaftarUser() {
  const { data, isLoading, error } = useQuery({
    queryKey: ["users"],
    queryFn: async () => {
      const res = await fetch("https://jsonplaceholder.typicode.com/users")
      if (!res.ok) throw new Error("Gagal memuat")
      return res.json()
    },
  })
 
  if (isLoading) return <p>Memuat...</p>
  if (error) return <p>Error: {error.message}</p>
  return <ul>{data.map((u) => <li key={u.id}>{u.name}</li>)}</ul>
}

useQuery({ queryKey, queryFn }) memberi cache otomatis, retry bawaan, dan background refetch saat window kembali fokus. queryKey menentukan identitas data — ganti saat parameter berubah.

SWR: Stale-While-Revalidate

SWR dari Vercel memakai strategi yang sama namanya: tampilkan data cache lama sambil mengambil data baru di background. useSWR(key, fetcher) memberi data, error, dan isLoading tanpa boilerplate. Episode 14 akan membahas strategi jaringan ini lebih dalam.

Penutup

Episode 8 menghubungkan React ke dunia luar: fetching dengan fetch, axios, dan async/await, pengelolaan tiga kondisi UI, normalisasi data, pola Suspense, lalu caching dan refetch otomatis dengan React Query atau SWR.

Inti yang harus dibawa pulang:

  • fetch tidak gagal pada status 4xx/5xx: selalu cek res.ok.
  • Kelola tiga kondisi secara eksplisit: loading, error, dan sukses.
  • Normalisasi data di layer khusus agar komponen tetap bersih.
  • Suspense menyatakan loading secara deklaratif; gunakan pola stabil untuk data.
  • React Query memberi cache, retry, dan background refetch otomatis.
  • SWR menampilkan cache lama sambil memperbarui di background.

Di episode 9 selanjutnya kita akan membahas routing & navigation — React Router dengan BrowserRouter, Routes, dan Route, nested routes, dynamic params, dan route guards, lalu Link, NavLink, redirect, serta code splitting berbasis route dengan lazy loading. Aplikasi kalian akan memiliki banyak halaman.

Belajar ReactJS - Data Fetching & Asynchronous UI | Belajar ReactJS