Supaya Tidak Double Fetch Begini Cara Fetch Data di Server Component Next Js

Cara fetch data di Server Component Next.js yang benar adalah membuat komponennya async lalu await fetch() langsung di dalamnya. Request independen yang digabung dalam satu fungsi fetch berantai atau dipanggil dua kali tanpa deduping membuat browser dan server mengambil data dua kali. Kuncinya ada di opsi cache dan pemisahan logika interaktif ke Client Component.

Jawaban Cepat: Pola Fetch yang Benar

Server Component berjalan di server, jadi tidak butuh useEffect atau useState untuk mengambil data awal. Cukup tandai fungsinya async.

async function Page() {
  const res = await fetch("https://api.example.com/posts", {
    next: { revalidate: 60 },
  });
  if (!res.ok) throw new Error("Gagal memuat data");
  const posts = await res.json();
  return (
    <ul>
      {posts.map((p) => <li key={p.id}>{p.title}</li>)}
    </ul>
  );
}
export default Page;
  • Jangan tambah “use client” di file yang hanya fetch dan render.
  • Jangan pakai hooks, window, document, atau localStorage di file ini.
  • Lempar error lewat throw agar ditangkap error.tsx.

Langkah Fetch Data di Server Component

Urutannya sederhana kalau file memakai App Router di app/page.tsx.

  1. Buat page.tsx sebagai async function dan export default.
  2. Panggil fetch dengan opsi cache yang sesuai kebutuhan data.
  3. Periksa res.ok sebelum res.json(), lalu render datanya.
  4. Pindahkan tombol, form, dan onClick ke Client Component terpisah.
// app/posts/LikeButton.tsx
"use client";
export default function LikeButton() {
  return <button onClick={() => alert("disukai")}>Suka</button>;
}

Perbandingan Opsi Cache Fetch

Perilaku cache menentukan kapan Next.js menghubungi API lagi. Salah pilih opsi ini penyebab umum double fetch atau data basi.

Pola Perilaku Kapan dipakai
force-cache Disimpan dan dipakai ulang Data jarang berubah
no-store Selalu ambil baru Data personal, real time
revalidate: 60 Cache 60 detik lalu refresh Daftar produk, artikel
  • Gunakan revalidate untuk keseimbangan cepat dan segar.
  • Pakai no-store hanya untuk data yang wajib baru tiap request.
  • Cek tab Network dan log Route Handler sebelum mematikan cache.

Parallel dan Sequential Fetch

Request yang tidak saling tergantung wajib jalan paralel. Request berantai baru boleh berurutan.

// Paralel
const [user, posts] = await Promise.all([
  fetch("https://api.example.com/user").then((r) => r.json()),
  fetch("https://api.example.com/posts").then((r) => r.json()),
]);

// Sequential
const userRes = await fetch("https://api.example.com/user");
const user = await userRes.json();
const orders = await fetch(
  `https://api.example.com/orders?user=${user.id}`
).then((r) => r.json());
  • Paralel memangkas waktu tunggu total.
  • Sequential dipakai kalau ID dari request pertama dibutuhkan request kedua.

FAQ

Apakah fetch di Server Component perlu useEffect?

Tidak. Cukup async await langsung di badan komponen.

Kenapa data tidak update setelah deploy?

Periksa opsi cache dan revalidate yang dipakai, kemungkinan halaman masih disajikan dari cache.

Di mana validasi form setelah fetch?

Tetap validasi di server sebelum mutate, walau client sudah memvalidasi.