React 19 Server Components: Yeni Nesil React Uygulamaları Geliştirme Rehberi
React 19 ile stabil hale gelen Server Components, frontend development'ta paradigma değişimi yaratıyor. Bu kapsamlı rehberde Server Components, Server Actions ve React 19'un getirdiği tüm yenilikleri detaylı inceliyoruz.
React 19 Server Components: Yeni Nesil React Uygulamaları Geliştirme Rehberi
5 Aralık 2024'te React 19'un stabil versiyonu yayınlandı ve web development dünyasında deprem etkisi yarattı. Yıllardır beta'da olan Server Components nihayet production-ready hale geldi. Ve bu, React'in tarihindeki en büyük paradigma değişimlerinden biri.
React 19 ile artık componentleriniz sunucuda render ediliyor, zero JavaScript ile client'a gönderilebiliyor ve %38'e varan performance kazançları sağlanabiliyor. Server Actions ile REST API'lara veda ediyoruz, useOptimistic ile optimistic updates artık çok daha kolay.
Bu kapsamlı rehberde React 19'un tüm yeniliklerini, Server Components'in nasıl çalıştığını, migration sürecini ve best practices'i detaylı şekilde inceleyeceğiz.
İçindekiler
- React 19 Neden Önemli?
- Server Components Nedir?
- Server vs Client Components
- Server Actions ile Form Yönetimi
- React 19 Yeni Hook'ları
- Performance İyileştirmeleri
- React 18'den React 19'a Migration
- Next.js 15 ve React 19 Entegrasyonu
- Production Best Practices
- Sık Sorulan Sorular
React 19 Neden Önemli?
React 19, sadece bir incremental update değil, React'in geleceğini şekillendiren foundational bir değişim. İşte neden bu kadar önemli olduğunu anlatan rakamlar:
Performance Kazançları:
- Server Components ile %38 daha hızlı initial load
- Client-side JavaScript bundle'da %60-70 azalma
- Hydration sürelerinde %45 iyileşme
Developer Experience:
- Server Actions ile API route sayısı %80 azalma
- Form management için external library ihtiyacı yok
- Daha az boilerplate, daha çok productivity
// React 18 - Kompleks form management
import { useState } from 'react'
function ContactForm() {
const [loading, setLoading] = useState(false)
const [error, setError] = useState(null)
async function handleSubmit(e) {
e.preventDefault()
setLoading(true)
setError(null)
try {
const formData = new FormData(e.target)
const response = await fetch('/api/contact', {
method: 'POST',
body: JSON.stringify(Object.fromEntries(formData)),
})
if (!response.ok) throw new Error('Failed')
} catch (err) {
setError(err.message)
} finally {
setLoading(false)
}
}
return (
<form onSubmit={handleSubmit}>
{/* Form fields... */}
{error && <div>{error}</div>}
<button disabled={loading}>
{loading ? 'Gönderiliyor...' : 'Gönder'}
</button>
</form>
)
}
// React 19 - Server Actions ile
function ContactForm() {
async function handleSubmit(formData) {
'use server'
const email = formData.get('email')
await sendEmail(email)
}
return (
<form action={handleSubmit}>
<input name="email" type="email" />
<button>Gönder</button>
</form>
)
}İkinci örnek daha clean, daha az kod ve daha iyi performance. İşte React 19'un gücü bu.
Server Components Nedir?
React Server Components (RSC), React componentlerinin sunucuda render edilip client'a optimize edilmiş format olarak gönderilmesini sağlıyor. Bu, geleneksel SSR'den (Server-Side Rendering) farklı ve çok daha güçlü.
SSR vs Server Components
Geleneksel SSR:
- Sunucuda HTML render et
- HTML'i client'a gönder
- JavaScript bundle'ı indir
- Hydration yap (React'i HTML'e "bağla")
Sonuç: İlk görsel hızlı ama interaktif olması yavaş, tüm JavaScript yine client'a gidiyor.
Server Components:
- Sunucuda component render et
- Zero JavaScript ile serialize edilmiş output gönder
- Sadece interaktif componentler için JavaScript indir
- Selective hydration
Sonuç: Hem hızlı görsel hem az JavaScript hem hızlı interaktivity.
Server Component Avantajları
// ProductList.server.jsx
import { db } from '@/lib/database'
// Bu component server'da çalışır, client'a JavaScript gönderilmez
export default async function ProductList() {
// Direkt database sorgusu - client'a expose olmaz
const products = await db.products.findMany({
include: { reviews: true }
})
// Pahalı hesaplamalar sunucuda yapılır
const averageRating = products.reduce((acc, p) =>
acc + p.reviews.reduce((sum, r) => sum + r.rating, 0) / p.reviews.length,
0
) / products.length
return (
<div>
<h1>Ürünler (Ortalama: {averageRating})</h1>
{products.map(product => (
<ProductCard key={product.id} product={product} />
))}
</div>
)
}Bu component'in avantajları:
- Zero Client JavaScript: ProductList için hiç JS gönderilmez
- Data Fetching: Direkt database access, API route'a gerek yok
- Security: Database credentials client'a expose olmaz
- Bundle Size: Client bundle'ında bu kod yok
Server vs Client Components
React 19'da her component varsayılan olarak Server Component. Client interactivity gerektiğinde 'use client' directive kullanıyorsunuz.
Ne Zaman Server Component?
- Data fetching
- Backend resource'lara erişim
- Sensitive bilgi (API keys, tokens)
- Büyük dependencies (syntax highlighter, markdown parser)
// BlogPost.server.jsx
import { Prism } from 'prism-react-renderer' // 45kb library
import { getPost } from '@/lib/cms'
export default async function BlogPost({ slug }) {
const post = await getPost(slug)
return (
<article>
<h1>{post.title}</h1>
<Prism language="javascript" code={post.code} />
</article>
)
}Prism library 45kb ama client'a hiç gönderilmez çünkü Server Component.
Ne Zaman Client Component?
- Event handlers (onClick, onChange)
- State ve lifecycle hooks (useState, useEffect)
- Browser-only APIs (localStorage, window)
- Interactivity gerektiren componentler
'use client'
import { useState } from 'react'
export function Counter() {
const [count, setCount] = useState(0)
return (
<button onClick={() => setCount(c => c + 1)}>
Count: {count}
</button>
)
}Composition Pattern
Server ve Client componentlerini compose edebilirsiniz:
// Page.server.jsx
import ClientCounter from './Counter.client'
export default async function Page() {
const data = await fetchData()
return (
<div>
<h1>Server Rendered: {data.title}</h1>
{/* Client component server component içinde */}
<ClientCounter initialValue={data.count} />
</div>
)
}Altın Kural: En üstte Server Component, interaktivite gerektiğinde Client Component ekleyin. Tersi (Client içinde Server) mümkün değil.
Server Actions ile Form Yönetimi
React 19'un en devrimci özelliklerinden biri Server Actions. Artık API route yazmadan, direkt sunucu fonksiyonlarını çağırabiliyorsunuz.
Basit Form Örneği
// app/actions/newsletter.js
'use server'
import { db } from '@/lib/database'
import { revalidatePath } from 'next/cache'
export async function subscribeNewsletter(formData) {
const email = formData.get('email')
// Validation
if (!email || !email.includes('@')) {
return { error: 'Geçersiz email' }
}
// Database işlemi
await db.subscribers.create({
data: { email, subscribedAt: new Date() }
})
// Cache invalidation
revalidatePath('/subscribers')
return { success: true }
}
// app/newsletter-form.jsx
import { subscribeNewsletter } from './actions/newsletter'
export function NewsletterForm() {
return (
<form action={subscribeNewsletter}>
<input name="email" type="email" required />
<button>Abone Ol</button>
</form>
)
}Zero JavaScript, tam çalışan form. Progressive enhancement!
Pending State ve useFormStatus
'use client'
import { useFormStatus } from 'react-dom'
function SubmitButton() {
const { pending } = useFormStatus()
return (
<button type="submit" disabled={pending}>
{pending ? 'Gönderiliyor...' : 'Gönder'}
</button>
)
}
export function ContactForm({ action }) {
return (
<form action={action}>
<input name="name" required />
<input name="email" type="email" required />
<textarea name="message" required />
<SubmitButton />
</form>
)
}useFormStatus parent form'un durumunu otomatik track ediyor.
Error Handling
'use client'
import { useActionState } from 'react'
import { createTodo } from './actions'
export function TodoForm() {
const [state, formAction] = useActionState(createTodo, { error: null })
return (
<form action={formAction}>
<input name="title" required />
{state?.error && (
<div className="error">{state.error}</div>
)}
<button>Ekle</button>
</form>
)
}
// actions.js
'use server'
export async function createTodo(prevState, formData) {
const title = formData.get('title')
if (title.length < 3) {
return { error: 'Başlık en az 3 karakter olmalı' }
}
await db.todos.create({ data: { title } })
revalidatePath('/todos')
return { error: null }
}React 19 Yeni Hook'ları
useOptimistic - Optimistic Updates Made Easy
'use client'
import { useOptimistic } from 'react'
import { likePost } from './actions'
export function LikeButton({ postId, initialLikes }) {
const [optimisticLikes, addOptimisticLike] = useOptimistic(
initialLikes,
(current, amount) => current + amount
)
async function handleLike() {
// UI'ı hemen güncelle
addOptimisticLike(1)
// Server'a gönder
await likePost(postId)
}
return (
<button onClick={handleLike}>
❤️ {optimisticLikes}
</button>
)
}Kullanıcı tıkladığında UI anında güncellenir, server response beklemez. Eski yöntemde onlarca satır kod gerektiren bu pattern artık 3 satır.
use - Resource Reading
import { use } from 'react'
function Comments({ commentsPromise }) {
// Promise'i direkt consume et
const comments = use(commentsPromise)
return (
<ul>
{comments.map(comment => (
<li key={comment.id}>{comment.text}</li>
))}
</ul>
)
}
// Parent component
export default async function Post({ id }) {
const postPromise = fetchPost(id)
const commentsPromise = fetchComments(id)
return (
<div>
<PostContent promise={postPromise} />
<Suspense fallback={<CommentsSkeleton />}>
<Comments commentsPromise={commentsPromise} />
</Suspense>
</div>
)
}use() hook'u Promise'leri ve Context'i consume edebiliyor. Conditional olarak kullanılabilir (diğer hook'lardan farklı).
useActionState - Form State Management
Daha önce örneklediğimiz bu hook, form submissions için state management sağlıyor:
const [state, formAction, isPending] = useActionState(serverAction, initialState)Performance İyileştirmeleri
React 19, sadece özelliklerle değil, core performance iyileştirmeleriyle de geliyor.
Automatic Batching Improvements
// React 18'de sadece event handlers içinde batch
setTimeout(() => {
setCount(c => c + 1) // Re-render
setFlag(f => !f) // Re-render
}, 1000)
// React 19'da her yerde automatic batching
setTimeout(() => {
setCount(c => c + 1)
setFlag(f => !f)
// Tek re-render!
}, 1000)Ref as Prop
// React 18
function Input({ inputRef }) {
return <input ref={inputRef} />
}
<Input inputRef={myRef} />
// React 19
function Input({ ref }) {
return <input ref={ref} />
}
<Input ref={myRef} />ref artık normal prop gibi geçilebiliyor, forwardRef wrapper'a gerek yok.
Document Metadata
export default function BlogPost({ post }) {
return (
<>
<title>{post.title}</title>
<meta name="description" content={post.excerpt} />
<link rel="canonical" href={`https://blog.com/${post.slug}`} />
<article>
<h1>{post.title}</h1>
{/* content */}
</article>
</>
)
}<title>, <meta> gibi elementler artık component içinde direkt kullanılabiliyor, React otomatik olarak document <head>'e taşıyor.
React 18'den React 19'a Migration
Breaking Changes
- Errors in Render: Artık render sırasında fırlatılan hatalar yakalanmıyor (consistency için)
- Removed: String Refs:
ref="myRef"syntax kaldırıldı - Removed: Legacy Context:
contextTypesAPI kaldırıldı - Removed: React.PropTypes: Flow/TypeScript kullanın
Migration Adımları
# 1. React 19'a güncelle
npm install react@latest react-dom@latest
# 2. TypeScript types güncelle
npm install -D @types/react@latest @types/react-dom@latest
# 3. ESLint config güncelle
npm install -D eslint-plugin-react-hooks@latest// package.json
{
"dependencies": {
"react": "^19.0.0",
"react-dom": "^19.0.0"
}
}Codemod Kullanımı
React ekibi migration için codemod sağlıyor:
npx codemod react/19/replace-string-refs
npx codemod react/19/replace-reactdom-render
npx codemod react/19/replace-act-importNext.js 15 ve React 19 Entegrasyonu
Next.js 15, React 19 ile birlikte çalışacak şekilde optimize edildi.
App Router ve Server Components
// app/products/page.jsx
import { db } from '@/lib/database'
import { AddToCartButton } from './add-to-cart-button'
export default async function ProductsPage() {
// Server Component - direkt DB access
const products = await db.products.findMany()
return (
<div>
{products.map(product => (
<div key={product.id}>
<h2>{product.name}</h2>
<p>${product.price}</p>
{/* Client Component */}
<AddToCartButton productId={product.id} />
</div>
))}
</div>
)
}
// app/products/add-to-cart-button.jsx
'use client'
import { addToCart } from './actions'
import { useOptimistic } from 'react'
export function AddToCartButton({ productId }) {
const [optimisticAdded, setOptimisticAdded] = useOptimistic(false)
async function handleClick() {
setOptimisticAdded(true)
await addToCart(productId)
}
return (
<button onClick={handleClick} disabled={optimisticAdded}>
{optimisticAdded ? 'Eklendi ✓' : 'Sepete Ekle'}
</button>
)
}Partial Prerendering (React 19.2)
React 19.2 (Ekim 2025) ile gelen Partial Prerendering:
export default async function ProductPage({ params }) {
return (
<div>
{/* Static part - CDN'den serve edilir */}
<ProductImages productId={params.id} />
{/* Dynamic part - runtime'da render edilir */}
<Suspense fallback={<PriceSkeleton />}>
<ProductPrice productId={params.id} />
</Suspense>
</div>
)
}Static kısım build time'da oluşur ve CDN'e konur, dynamic kısım request time'da doldurulur.
Production Best Practices
1. Server/Client Component Split
✅ İyi:
app/
├── layout.jsx (Server)
├── page.jsx (Server)
├── components/
│ ├── header.jsx (Server)
│ ├── user-menu.client.jsx (Client)
│ └── theme-toggle.client.jsx (Client)
❌ Kötü:
app/
├── layout.client.jsx (Gereksiz client)
├── page.client.jsx (Tüm sayfa client)
Client componentleri mümkün olduğunca leaf node'larda tutun.
2. Data Fetching Patterns
// ❌ Waterfall - yavaş
async function Page() {
const user = await fetchUser()
const posts = await fetchPosts(user.id) // user bekliyor
return <div>{posts.map(...)}</div>
}
// ✅ Parallel - hızlı
async function Page() {
const [user, posts] = await Promise.all([
fetchUser(),
fetchPosts()
])
return <div>{posts.map(...)}</div>
}
// ✅ Streaming - en hızlı UX
async function Page() {
const userPromise = fetchUser()
const postsPromise = fetchPosts()
return (
<div>
<Suspense fallback={<UserSkeleton />}>
<User promise={userPromise} />
</Suspense>
<Suspense fallback={<PostsSkeleton />}>
<Posts promise={postsPromise} />
</Suspense>
</div>
)
}3. Cache Stratejileri
// Aggressive caching
export const revalidate = 3600 // 1 saat
async function getData() {
const res = await fetch('https://api.example.com/data', {
next: { revalidate: 3600 }
})
return res.json()
}
// On-demand revalidation
'use server'
import { revalidateTag } from 'next/cache'
export async function updateProduct(id) {
await db.products.update(id)
revalidateTag('products') // Cache'i invalidate et
}Sık Sorulan Sorular
React 19 production-ready mi?
Evet! 5 Aralık 2024'te stable release yayınlandı. Meta Facebook'ta production'da kullanıyor.
Mevcut React 18 projemi güncellemeli miyim?
Yeni özellikler istemiyorsanız acele etmeyin. React 18 uzun süre desteklenecek. Ancak yeni projelerde React 19 tercih edilmeli.
Server Components sadece Next.js'te mi çalışır?
Hayır, Remix, Gatsby ve diğer framework'ler de Server Components desteği ekliyor. Ancak en mature desteği Next.js sunuyor.
Server Actions güvenli mi?
Evet, Server Actions varsayılan olarak POST endpoint'leri ve Next.js tarafından CSRF korumalı. Ancak yine de input validation şart.
Client-side router gerekiyor mu?
Next.js App Router Server Components ile native çalışıyor. React Router gibi client-side router'lar henüz full support sağlamıyor.
Bundle size gerçekten küçülüyor mu?
Evet, Server Components kullanan uygulamalarda ortalama %60-70 bundle size azalması görülüyor.
Sonuç
React 19 ve Server Components, modern web development'ın yönünü değiştiriyor. Zero JavaScript ile fast initial load, Server Actions ile kolay backend integration ve yeni hook'larla improved DX. Bunlar sadece incremental improvements değil, paradigm shift.
Eğer yeni bir React projesi başlatıyorsanız, React 19 + Next.js 15 kombinasyonu şu an mevcut en güçlü stack. Mevcut projelerinizi güncellemek için acele etmenize gerek yok, ancak Server Components pattern'lerini öğrenmeye şimdiden başlamalısınız.
React'in geleceği server-first. Bu trene erken binmek, career'inize büyük katkı sağlayacak.
Aksiyon Öğeleri:
- Küçük bir side project ile React 19 deneyin
- Server vs Client component ayrımını öğrenin
- Server Actions ile API route'suz development pratik yapın
- useOptimistic ile modern UX pattern'leri keşfedin
- Next.js 15 documentation'ını inceleyin
Mutlu kodlamalar!
Projenizi Hayata Geçirelim
Web sitesi, mobil uygulama veya yapay zeka çözümü mü arıyorsunuz? Fikirlerinizi birlikte değerlendirelim.
Ücretsiz Danışmanlık Alın