nextjsfetchdataMenengah4 mnt baca

Fetch di Server Component

Pola dasar: async component + fetch langsung tanpa useEffect.

Fetch langsung di Server Component: pola paling sederhana

Bayangkan sebuah restoran. Di pola lama (React SPA), pelayan (browser) harus bolak-balik ke pasar (API) setiap kali tamu memesan: ambil bahan, kembali, baru masak, baru hidang. Tamu menunggu lama dan melihat dapur yang kosong dulu (loading spinner). Di Next.js App Router, juru masak (server) mengambil bahan sendiri dari pasar SEBELUM tamu duduk. Saat hidangan sampai ke meja, semuanya sudah siap.

Itulah kenapa pola ini ada. Di era useEffect, setiap halaman mengambil datanya di browser: JavaScript dimuat dulu, efek berjalan, request dikirim, loading tampil, data datang, baru render. Tiga masalah muncul: pengguna melihat layar kosong atau loading, mesin pencari (crawler) sering hanya melihat kerangka kosong sehingga SEO jeblok, dan API key yang dipakai di client bisa diintip siapa saja lewat DevTools.

Server Component membalik alurnya. Komponen page.tsx boleh async, dan await fetch() di dalamnya berjalan di server, sebelum satu byte HTML pun dikirim ke browser. Hasilnya: HTML yang sampai sudah berisi data lengkap.

tsx
// app/users/page.tsx
export default async function Users() {
  const res = await fetch("https://jsonplaceholder.typicode.com/users");
  if (!res.ok) throw new Error("Gagal memuat daftar user");
  const users: { id: number; name: string }[] = await res.json();

  return (
    <ul>
      {users.map((u) => (
        <li key={u.id}>{u.name}</li>
      ))}
    </ul>
  );
}

Perhatikan betapa datarnya kode ini: tidak ada useState, tidak ada useEffect, tidak ada state loading. Komponennya async seperti fungsi biasa, dan itu legal hanya di Server Component.

Contoh kedua: halaman yang datanya harus selalu segar, misalnya daftar harga atau stok. Secara default fetch di Server Component di-cache (dibahas tuntas di modul caching), jadi untuk data real-time tambahkan cache: "no-store":

tsx
// app/stok/page.tsx
export default async function Stok() {
  const res = await fetch("https://api.example.com/stok", {
    cache: "no-store", // selalu ambil data terbaru
  });
  const items = await res.json();
  return <StockTable items={items} />;
}

Kenapa tanpa useEffect?

Karena fetch-nya terjadi di server sebelum HTML dikirim: tidak ada loading state manual (Next.js menanganinya lewat Suspense otomatis), tidak ada waterfall di client, dan SEO mendapat konten penuh karena crawler menerima HTML yang sudah jadi. Bonus keamanan: API key atau database credential yang dipakai di sini tidak pernah sampai ke browser.

Perbandingan singkat

Server fetchuseEffect fetch
Loading stateOtomatis (Suspense)Ditulis manual
SEOKonten penuh saat crawlSering kosong saat crawl
Secret/API keyAman di serverTerlihat di browser

Aturan main: pola async + await fetch hanya untuk Server Component. Kalau komponenmu butuh interaktivitas (onClick, useState), ia adalah Client Component, dan fetch di sana dibahas di modul fetch-client-component. Jangan campur: fetch data awal di server, interaksi di client.

Tantangan

Daftar user

Buat halaman /users yang fetch 10 user dari jsonplaceholder langsung di Server Component. Matikan JavaScript di browser dan buktikan daftar tetap tampil.