Next.js 15 Sıfırdan Başlangıç

Ders 7/8 30 dakika

Statik ve Dinamik Veri Çekme

Server Components içinde async/await ile veri çekme, statik ve dinamik render farkı, ve revalidate ile ISR kullanımı.

Server Components\'ta Veri Çekme

Next.js 15\'in en güçlü özelliği: Server Component\'lar doğrudan async fonksiyon olabilir. Veritabanına, API\'ye doğrudan bağlanabilirsiniz — tarayıcıda hiçbir şey çalışmaz, kod sunucuda kalır.

// app/blog/page.tsx — Bu bir Server Component
export default async function BlogListesi() {
  // Bu kod SUNUCUDA çalışır — API anahtarları güvende
  const yanit = await fetch("https://api.ornek.com/yazilar");
  const yazilar = await yanit.json();

  return (
    <div>
      {yazilar.map((yazi: any) => (
        <article key={yazi.id}>
          <h2>{yazi.baslik}</h2>
          <p>{yazi.ozet}</p>
        </article>
      ))}
    </div>
  );
}

Statik vs Dinamik Render

DavranışAçıklamaNe zaman?
StaticBuild sırasında render edilir, CDN\'de önbelleklenirBlog, landing page, statik içerik
DynamicHer istek için sunucuda render edilirDashboard, kullanıcıya özgü içerik
ISRBelirli aralıkta yeniden oluşturulurHaber sitesi, fiyat listesi

Caching Kontrolü

// 1. Statik — build sırasında cache\'lenir (default)
const veri = await fetch("https://api.com/veri");

// 2. Dinamik — cache YOK, her istekte çekilir
const veri = await fetch("https://api.com/veri", {
  cache: "no-store",
});

// 3. ISR — 60 saniyede bir yeniden doğrula
const veri = await fetch("https://api.com/veri", {
  next: { revalidate: 60 },
});

Paralel Veri Çekme

export default async function Dashboard() {
  // ✅ Paralel çekme — biri bitmesini beklemez
  const [kullanici, siparisler, istatistikler] = await Promise.all([
    fetch("/api/kullanici").then(r => r.json()),
    fetch("/api/siparisler").then(r => r.json()),
    fetch("/api/istatistikler").then(r => r.json()),
  ]);

  return <div>...</div>;
}

loading.tsx ile Skeleton

// app/blog/loading.tsx
export default function Loading() {
  return (
    <div className="space-y-4">
      {[...Array(3)].map((_, i) => (
        <div key={i} className="animate-pulse">
          <div className="h-6 bg-gray-200 rounded w-3/4 mb-2"></div>
          <div className="h-4 bg-gray-200 rounded w-1/2"></div>
        </div>
      ))}
    </div>
  );
}

Önemli Noktalar

  • Server Components async fonksiyon olabilir — doğrudan await kullanın
  • fetch ile cache kontrolü: no-store (dinamik) veya revalidate (ISR)
  • Promise.all ile paralel veri çekin — seri bekleme yapmayın
  • loading.tsx otomatik Suspense sınırı oluşturur