Belajar ReactJS - API Integration & Error Handling
Episode 13 of 24

Belajar ReactJS - API Integration & Error Handling

Episode ini mengajarkan konsumsi REST dan GraphQL API, fetch policies dengan retries dan retry delays, centralized error handling lengkap dengan fallback UI, serta preloading data dan optimistic updates untuk pengalaman pengguna yang lebih baik.

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

Pendahuluan

Integrasi API yang buruk terasa di tangan pengguna: spinner berputar tanpa henti, request gagal tanpa penjelasan, atau daftar yang tidak sinkron setelah aksi. Episode 13 membuat integrasi kalian tangguh.

Kita mulai dari konsumsi REST dan GraphQL, lalu membahas fetch policies dengan retries dan retry delays, centralized error handling dengan fallback UI yang baik, dan ditutup dua pola UX canggih: preloading data dan optimistic updates.

Konsumsi REST API dan GraphQL API

REST dengan Layer API Terpisah

Pisahkan logika API dari komponen dengan membuat module sendiri. Ini memudahkan pemakaian ulang dan pengujian:

JSLayer API terpisah
// src/api/users.js
export async function getUsers() {
  const res = await fetch("https://api.example.com/users")
  if (!res.ok) throw new Error(`HTTP ${res.status}`)
  return res.json()
}
 
// komponen memanggil
import { getUsers } from "../api/users.js"
const users = await getUsers()

export async function getUsers() mengisolasi detail endpoint ke satu tempat. Komponen hanya tahu fungsi ini mengembalikan array users atau melempar error.

GraphQL dengan gql

Untuk GraphQL, query dibangun dengan bahasa query dan dikirim via HTTP POST. Memakai library seperti urql atau @apollo/client:

JSQuery GraphQL dengan urql
import { useQuery, gql } from "urql"
 
const USERS_QUERY = gql`
  query {
    users {
      id
      name
    }
  }
`
 
function DaftarUser() {
  const [result] = useQuery({ query: USERS_QUERY })
  if (result.fetching) return <p>Memuat...</p>
  if (result.error) return <p>Error: {result.error.message}</p>
  return <ul>{result.data.users.map((u) => <li key={u.id}>{u.name}</li>)}</ul>
}

useQuery({ query: USERS_QUERY }) menjalankan query GraphQL dan memberi fetching, error, dan data. Keunggulan GraphQL: klien hanya mengambil field yang benar-benar dibutuhkan.

Fetch Policies, Retries, dan Retry Delays

Retry Otomatis dengan TanStack Query

Jaringan tidak bisa diandalkan. Retries dengan jeda eksponensial membuat request sementara gagal menjadi sukses otomatis:

JSRetry dengan TanStack Query
import { useQuery } from "@tanstack/react-query"
 
function DaftarUser() {
  const { data, error, refetch } = useQuery({
    queryKey: ["users"],
    queryFn: getUsers,
    retry: 3,
    retryDelay: (attempt) => Math.min(1000 * 2 ** attempt, 30000),
  })
 
  if (error) return (
    <div>
      <p>Gagal memuat data</p>
      <button onClick={() => refetch()}>Coba lagi</button>
    </div>
  )
  return <ul>{data?.map((u) => <li key={u.id}>{u.name}</li>)}</ul>
}

retry: 3 mencoba ulang hingga tiga kali, dan retryDelay: (attempt) => Math.min(1000 * 2 ** attempt, 30000) memakai jeda eksponensial dengan batas 30 detik — mencegah membebani server saat jaringan turun.

Centralized Error Handling dan Fallback UI

Error Boundary untuk Render, State untuk Data

Tangan dua jenis error secara berbeda:

  • Error render (bug di komponen) ditangkap oleh error boundaries dari episode 7.
  • Error data (request gagal) ditangani per query dengan state dan UI fallback.
JSFallback UI yang informatif
function Fallback({ pesan, onRetry }) {
  return (
    <div role="alert">
      <p>Maaf, terjadi kesalahan: {pesan}</p>
      <button onClick={onRetry}>Muat ulang</button>
    </div>
  )
}

<div role="alert">{:javascript}</div> mengumumkan error ke screen reader. Fallback yang baik memberi tahu apa yang salah dan memberi jalan keluar — bukan sekadar layar kosong.

Centralize: Satu Cara Memanggil API

Centralized error handling berarti semua request melewati satu titik yang konsisten menangani kegagalan — misalnya axios interceptor yang menangkap status 401 untuk logout otomatis, atau hook useApi yang membungkus useQuery dengan konfigurasi error seragam. Satu perubahan kebijakan cukup di satu tempat.

Preloading Data dan Optimistic Updates

Preloading: Siapkan Sebelum Dibutuhkan

Preloading mengambil data lebih awal, misalnya saat pengguna mengarahkan kursor ke tombol, sehingga halaman target terasa instan:

JSPrefetch saat hover
import { useQueryClient } from "@tanstack/react-query"
 
function Menu() {
  const queryClient = useQueryClient()
 
  const prefetchUsers = () => {
    queryClient.prefetchQuery({ queryKey: ["users"], queryFn: getUsers })
  }
 
  return <Link to="/users" onMouseEnter={prefetchUsers}>Pengguna</Link>
}

queryClient.prefetchQuery({ queryKey: ["users"], queryFn: getUsers }) mengambil data di background saat kursor masuk link. Ketika halaman terbuka, data sudah ada di cache — tanpa spinner.

Optimistic Updates: UI Mendahului Server

Untuk aksi cepat seperti suka atau hapus, optimistic update mengubah UI dulu lalu memperbarui server di belakang:

JSOptimistic update
const { mutate } = useMutation({
  mutationFn: hapusUser,
  onMutate: async (id) => {
    await queryClient.cancelQueries({ queryKey: ["users"] })
    queryClient.setQueryData(["users"], (old) =>
      old.filter((u) => u.id !== id)
    )
  },
})

onMutate langsung memperbarui cache sebelum respons server datang. Jika server gagal, gunakan onError untuk mengembalikan cache ke keadaan semula — dan tampilkan pesan singkat bahwa sinkronisasi gagal.

Install klien GraphQL untuk praktik
npm install urql graphql

Perintah npm install urql graphql memasang klien GraphQL. Coba ganti salah satu fetching REST kalian dengan query GraphQL untuk merasakan perbedaannya.

Penutup

Episode 13 membuat integrasi API kalian tangguh: layer API untuk REST dan GraphQL, retries dengan jeda eksponensial, centralized error handling dengan fallback UI, lalu preloading dan optimistic updates untuk UX yang mulus.

Inti yang harus dibawa pulang:

  • Pisahkan logika API ke module terpisah agar mudah dipakai ulang dan diuji.
  • GraphQL memakai query untuk mengambil field yang dibutuhkan.
  • Retry otomatis dengan jeda eksponensial menahan gangguan jaringan sementara.
  • Error boundary menangani error render; state menangani error data.
  • Fallback UI wajib memberi pesan dan jalan keluar.
  • Prefetch dan optimistic update membuat UI terasa responsif.

Di episode 14 selanjutnya kita akan membahas networking performance — HTTP caching dan stale-while-revalidate, code splitting dan bundle analysis, prefetching data dan assets, serta monitoring performa jaringan. Aplikasi kalian tidak hanya berfungsi, tapi juga cepat.

Belajar ReactJS - API Integration & Error Handling | Belajar ReactJS