Performance & Scalability serimizin bir parçası
Tam kılavuzu okuyunReact 19 Sunucu Bileşeni: Neler Değişti ve Neden
React 19, Hook'lardan bu yana en önemli sürümdür. React 18'de deneysel bir özellik olarak başlayan Sunucu Bileşenleri artık stabildir ve eş zamanlı işleme modeliyle tamamen entegredir. Ancak değişiklikler RSC'yi stabilize etmenin çok ötesine geçiyor — React 19, React uygulamalarındaki veri akışı hakkındaki düşüncelerinizi toplu olarak değiştiren Actions'ı, yeni bir use() kancasını, form entegrasyonunu, iyimser güncellemeleri ve belge meta veri yönetimini sunuyor.
Bu kılavuz, React 18 ile 19 arasında gerçekte nelerin değiştiğine odaklanmakta, her değişikliğin arkasındaki mimari mantığı açıklamakta ve eski yaklaşımların yerini alan üretim modellerini göstermektedir.
Önemli Çıkarımlar
- Sunucu Bileşenleri yalnızca sunucuda çalışır; yaşam döngüleri, durumları ve tarayıcı API'leri yoktur
use()kancası, vaatleri ve bağlamı tüketmek için İstemci Bileşenlerindeawait'nin yerini alır- React 19 Eylemleri, form gönderimleri için manuel
useState+fetchmodellerinin yerini alıruseOptimistic, sunucu onayından önce anında kullanıcı arayüzü güncellemelerine olanak sağlaruseFormStatussize form bileşenlerini detaylandırmadan bekleme durumunu verir- Varlık önyükleme API'leri (
preload,preinit), bileşenlerden kaynak yüklemeyi kontrol etmenize olanak tanır- Bileşenlerdeki
<title>,<meta>ve<link>etiketleri otomatik olarak<head>konumuna kaldırılır- Sunucu Bileşenleri ve İstemci Bileşenleri bir ağaç oluşturur — İstemci Bileşenleri, Sunucu Bileşenlerini içe aktaramaz
Sunucu Bileşenleri Gerçekte Nelerdir?
Neyin değiştiğini tartışmadan önce, Sunucu Bileşenlerinin ne olduğunu açıklayın: Yalnızca sunucuda oluşturulan ve istemcinin hidratladığı HTML + RSC yükünü üreten reaksiyona giren bileşenler. Bunlar, sunucu tarafında oluşturulan İstemci Bileşenleriyle aynı değildir.
Temel farklar:
| Sunucu Bileşenleri | İstemci Bileşenleri | |
|---|---|---|
| Çalıştırılıyor | Yalnızca sunucu | Sunucu (ilk oluşturma) + İstemci |
| Kancaları kullanabilir | Hayır | Evet |
| Tarayıcı API'lerini kullanabilir | Hayır | Evet |
| Veritabanına erişebilir | Evet (doğrudan) | Hayır (API aracılığıyla) |
| Paket boyutu etkisi | Sıfır | Evet |
| Eşzamansız olabilir | Evet | Hayır (Askıda Olmadan) |
// Server Component — async, no hooks, direct DB access
async function UserProfile({ userId }: { userId: string }) {
// Direct database query — no API needed
const user = await db.query.users.findFirst({
where: eq(users.id, userId),
});
return (
<div>
<h1>{user.name}</h1>
{/* Client Component gets data as props */}
<UserActions userId={user.id} role={user.role} />
</div>
);
}
// Client Component — can use hooks, handles interactions
'use client';
function UserActions({ userId, role }: { userId: string; role: string }) {
const [isEditing, setIsEditing] = useState(false);
return (
<div>
<button onClick={() => setIsEditing(true)}>Edit</button>
{isEditing && <EditUserForm userId={userId} />}
</div>
);
}
19 Eyleme Tepki Ver
React 19'daki en büyük ergonomik gelişme, özellikle form gönderimleri olmak üzere kullanıcı etkileşimleri tarafından tetiklenen eşzamansız işlemleri yönetmenin standartlaştırılmış bir yolu olan Eylemler'dir.
React 19'dan önce form işleme tekrarlanan bir standarttı:
// React 18 — manual state management
function ContactForm() {
const [name, setName] = useState('');
const [email, setEmail] = useState('');
const [submitting, setSubmitting] = useState(false);
const [error, setError] = useState<string | null>(null);
async function handleSubmit(e: React.FormEvent) {
e.preventDefault();
setSubmitting(true);
setError(null);
try {
await createContact({ name, email });
} catch (err) {
setError(err.message);
} finally {
setSubmitting(false);
}
}
return (
<form onSubmit={handleSubmit}>
{/* ... */}
</form>
);
}
React 19 Actions bunu önemli ölçüde kolaylaştırıyor:
// React 19 — useActionState
'use client';
import { useActionState } from 'react';
async function createContactAction(
prevState: { error?: string },
formData: FormData
) {
'use server'; // Server Action — runs on the server
const name = formData.get('name') as string;
const email = formData.get('email') as string;
try {
await createContact({ name, email });
return { success: true };
} catch (err) {
return { error: err.message };
}
}
function ContactForm() {
const [state, formAction, isPending] = useActionState(
createContactAction,
{}
);
return (
<form action={formAction}>
<input name="name" required />
<input name="email" type="email" required />
{state.error && <p className="text-red-500">{state.error}</p>}
<button type="submit" disabled={isPending}>
{isPending ? 'Submitting...' : 'Submit'}
</button>
</form>
);
}
useActionState kancası bekleme durumunu, form verilerini ve hata işlemeyi tek bir yerden yönetir. Eylem işlevindeki 'use server' yönergesi onu bir Sunucu Eylemi olarak işaretler; sunucuda çalışır, veritabanına doğrudan erişebilir ve istemci uygulamayı asla görmez.
Sunucu Eylemleri
Sunucu Eylemleri, istemciden çağrıldığında sunucuda çalışan 'use server' yönergesine sahip eşzamansız işlevlerdir. Çoğu veri mutasyonu kullanım durumu için API rotalarının yerini alırlar:
// app/actions/contacts.ts
'use server';
import { revalidatePath } from 'next/cache';
import { redirect } from 'next/navigation';
import { db } from '@ecosire/db';
import { contacts } from '@ecosire/db/schema';
export async function createContact(formData: FormData) {
const name = formData.get('name') as string;
const email = formData.get('email') as string;
if (!name || !email) {
throw new Error('Name and email are required');
}
await db.insert(contacts).values({
name,
email,
organizationId: await getOrganizationId(), // From session
});
revalidatePath('/dashboard/contacts'); // Invalidate cached page
redirect('/dashboard/contacts'); // Redirect after success
}
Sunucu Eylemleri doğrudan form öğelerinde kullanılabilir:
import { createContact } from '@/app/actions/contacts';
export default function NewContactPage() {
return (
<form action={createContact}>
<input name="name" placeholder="Name" required />
<input name="email" placeholder="Email" type="email" required />
<button type="submit">Create Contact</button>
</form>
);
}
onSubmit işleyicisi yok, preventDefault() yok, fetch() kılavuzu yok — form sadece çalışıyor.
Kullanım() Kancası
React 19, render içindeki kaynakları (Vaatler ve Bağlam) tüketmek için use() kancasını sunar. await'den farklı olarak React'ın Suspense sistemiyle çalışır:
// Before React 19 — had to resolve at the top level
export default async function Page() {
const posts = await getPosts(); // Blocks entire page
return <PostList posts={posts} />;
}
// React 19 — pass a promise, resolve with use()
export default function Page() {
const postsPromise = getPosts(); // Start fetch immediately
return (
<Suspense fallback={<PostsSkeleton />}>
<PostList postsPromise={postsPromise} />
</Suspense>
);
}
// Client Component using use() to consume the promise
'use client';
function PostList({ postsPromise }: { postsPromise: Promise<Post[]> }) {
const posts = use(postsPromise); // Suspends until resolved
return (
<ul>
{posts.map((post) => (
<li key={post.id}>{post.title}</li>
))}
</ul>
);
}
use() kancası ayrıca useContext()'nin yerine geçer — bağlamı koşullu olarak tüketebilir (kancaların aksine, use() koşullar ve döngüler içinde çağrılabilir):
'use client';
import { use } from 'react';
import { ThemeContext } from '@/contexts/theme';
function Button({ children }: { children: React.ReactNode }) {
const theme = use(ThemeContext); // Can be inside conditions
return (
<button className={theme === 'dark' ? 'bg-gray-800' : 'bg-white'}>
{children}
</button>
);
}
UseOptimistic ile İyimser Güncellemeler
useOptimistic, bir sunucu işlemi tamamlanmadan önce anında kullanıcı arayüzü geri bildirimi sağlar ve işlem başarısız olursa otomatik olarak geri döner:
'use client';
import { useOptimistic, useTransition } from 'react';
interface Like {
id: string;
count: number;
userLiked: boolean;
}
function LikeButton({ postId, initialLikes }: { postId: string; initialLikes: Like }) {
const [likes, setOptimisticLikes] = useOptimistic(
initialLikes,
(state, action: 'like' | 'unlike') => ({
...state,
count: action === 'like' ? state.count + 1 : state.count - 1,
userLiked: action === 'like',
})
);
const [isPending, startTransition] = useTransition();
async function toggleLike() {
const action = likes.userLiked ? 'unlike' : 'like';
startTransition(async () => {
setOptimisticLikes(action); // Instant UI update
// Server operation — if this fails, optimistic state reverts
await togglePostLike(postId, action);
});
}
return (
<button onClick={toggleLike} disabled={isPending}>
{likes.userLiked ? '♥' : '♡'} {likes.count}
</button>
);
}
İyimser güncelleme hemen gösterilir, ardından ya işleme alınır (sunucu başarısı) ya da geri alınır (sunucu hatası). Kullanıcılar ağ gidiş dönüşlerini beklemeden anında geri bildirim alırlar.
Bileşenlerden Meta Verileri Belgeleyin
React 19, <title>, <meta> ve <link> etiketlerinin herhangi bir bileşenin içinde oluşturulmasına olanak tanır; bunlar otomatik olarak <head> belgesine kaldırılır:
// Server Component — metadata hoists to <head> automatically
async function BlogPost({ slug }: { slug: string }) {
const post = await getPost(slug);
return (
<article>
<title>{post.title}</title>
<meta name="description" content={post.description} />
<link rel="canonical" href={`https://ecosire.com/blog/${slug}`} />
<h1>{post.title}</h1>
<div>{post.content}</div>
</article>
);
}
Bu hem Sunucu hem de İstemci Bileşenlerinde çalışır. Next.js gibi çerçevelerde, OpenGraph etiketleri ve hreflang nitelikleri üzerinde tam kontrol için hala generateMetadata() kullanacaksınız — React 19'un yerel desteği daha basittir. Ancak basit durumlarda next/head veya benzeri kütüphanelere olan ihtiyacı ortadan kaldırır.
Varlık Yükleme API'leri
React 19, kaynakların önceden yüklenmesi için açık API'ler sunarak kaynak yükleme şelalesi üzerinde ayrıntılı kontrol sağlar:
import { preload, preinit, prefetchDNS, preconnect } from 'react-dom';
function BelowFoldSection() {
// When this component renders, preload the hero image for next section
preload('/images/hero-next.webp', { as: 'image' });
// Preinit a script (loads and executes immediately)
preinit('https://cdn.example.com/analytics.js', { as: 'script' });
// DNS prefetch for external resources
prefetchDNS('https://fonts.googleapis.com');
// Establish connection early
preconnect('https://api.ecosire.com');
return <section>{/* content */}</section>;
}
Bu API'ler, React'in oluşturma modeliyle doğru şekilde çalışır; kaynak ipuçlarını toplu olarak toplar ve bunları belgenin en uygun noktasında, hatta bileşen ağacının derinliklerinden bile yayar.
Yaygın Tuzaklar ve Çözümler
Tuzak 1: Sunucu Bileşenlerinde kanca kullanmaya çalışmak
Sunucu Bileşenleri useState, useEffect, useContext veya başka herhangi bir kancayı kullanamaz. Bunlara ihtiyacınız varsa bileşene 'use client' ekleyin. Hata genellikle şu şekildedir: Error: Hooks can only be called inside a function component.
Tuzak 2: Sunucu Bileşenlerini İstemci Bileşenlerinden İçe Aktarma
İstemci Bileşenleri, Sunucu Bileşenlerini içe aktaramaz (tersi de sorun değildir). Bunun nedeni, İstemci Bileşenlerinin, Sunucu Bileşenlerinin bulunmadığı tarayıcıda çalışmasıdır. Bunları oluşturmanız gerekiyorsa Sunucu Bileşenlerini children desteği olarak iletin:
// Wrong — Client Component cannot import Server Component
'use client';
import { ServerUserProfile } from './server-user-profile'; // Error
// Correct — pass as children from a Server Component parent
// Parent (Server):
<ClientShell>
<ServerUserProfile userId={userId} />
</ClientShell>
// ClientShell:
'use client';
function ClientShell({ children }: { children: React.ReactNode }) {
return <div className="shell">{children}</div>;
}
Tuzak 3: Donanımları Sunucudan İstemciye aktarırken serileştirme hataları
Yalnızca JSON ile serileştirilebilir veriler Sunucu-İstemci sınırını destek olarak geçebilir. İşlevler, sınıf örnekleri, Harita, Küme ve Tarihler (nesneler olarak) serileştirilemez. Tarihleri ISO dizelerine dönüştürün; işlevleri dize tanımlayıcılarla değiştirin.
4. Tuzak: Sunucu Eylemleri girişi doğrulamıyor
Sunucu Eylemlerinde istemci tarafından sağlanan verilere asla güvenmeyin. Veritabanına yazmadan önce daima Zod veya benzeri bir programla doğrulayın:
'use server';
import { z } from 'zod';
const schema = z.object({
name: z.string().min(2).max(255),
email: z.string().email(),
});
export async function createContact(formData: FormData) {
const result = schema.safeParse({
name: formData.get('name'),
email: formData.get('email'),
});
if (!result.success) {
return { error: result.error.flatten().fieldErrors };
}
await db.insert(contacts).values(result.data);
}
Sıkça Sorulan Sorular
Sunucu Bileşenleri Next.js dışında da mevcut mu?
React Sunucu Bileşenleri bir React özelliğidir ancak sunucu oluşturma altyapısını (yönlendirme, paketleme, akış) yönetmek için bir çerçeve gerektirirler. Next.js Uygulama Yönlendiricisi en olgun uygulamadır. Remix, Astro ve Vite tabanlı kurulumlara RSC desteği ekleniyor. RSC'yi bir çerçeve olmadan kullanmak, önemli miktarda özel altyapı çalışması gerektirir.
Sunucu Eylemleri, REST API rotalarıyla karşılaştırıldığında nasıldır?
Sunucu Eylemleri, kullanıcı arayüzüyle aynı yerde bulunan mutasyonlar için daha basittir; yönetilecek uç nokta URL'si yok, yazılacak fetch() çağrısı yok, ortak metinde hata işleme yok. REST API rotaları, web uygulamasının dışından çağrılan işlemler (mobil uygulamalar, web kancaları, üçüncü taraf entegrasyonları), dokümantasyon gerektiren genel API'ler ve açık HTTP durum kodlarına ihtiyacınız olduğunda daha iyidir. Kullanım durumuna göre her ikisini de aynı uygulamada kullanın.
Sunucu Bileşenlerinin performansa etkisi nedir?
Sunucu Bileşenleri, JavaScript paket boyutunu küçültür (bileşen kodu hiçbir zaman tarayıcıya gönderilmez), istemci tarafı veri getirme şelalelerini ortadan kaldırır ve Suspense yoluyla akışlı HTML dağıtımını etkinleştirir. Buradaki ödünleşim, sunucu bilgi işlem maliyetidir; oluşturma, müşterinin cihazında değil, sunucularınızda gerçekleşir. Veri ağırlıklı sayfalar için bu neredeyse her zaman net bir kazançtır.
React 18 ve React 19'u bir kod tabanında karıştırabilir miyim?
Tüm React kodları React 19 olarak çalışır; dosya başına sürüm oluşturma yoktur. Soru, mevcut React 18 kodunuzun React 19'da çalışıp çalışmadığıdır. React 18 kodlarının çoğu değişmeden çalışır. En önemli değişiklikler referanslar (artık normal bir özellik), ReactDOM.render'ın kaldırılması ve @types/react'deki bazı yazma değişiklikleriyle ilgili. Otomatik geçiş için React 19 kod modlarını çalıştırın.
Sunucu Bileşenlerini nasıl test ederim?
Sunucu Bileşenleri, async render kullanılarak React Testing Library ile test edilebilir. Sunucu Eylemleri için bunları sahte veritabanı çağrılarıyla düz eşzamansız işlevler olarak test edin. Playwright ile yapılan uçtan uca testler, herhangi bir özel kurulum gerektirmeden tam Sunucu Bileşeni + İstemci Bileşeni entegrasyonunu kapsar; nihai HTML çıktısını test ederler.
Sonraki Adımlar
React 19 Sunucu Bileşenleri, modern web uygulamalarının oluşturulmasında temel bir değişimi temsil ediyor. ECOSIRE'ın ön uç ekibi bu mimari üzerinde üretim uygulamaları geliştirdi; Sunucu Bileşenleri, Sunucu Eylemleri ve gerçek kullanıcı iş akışlarına güç veren iyimser güncellemeler içeren 249 sayfa.
React 18'den 19'a geçiş, yeni bir RSC öncelikli uygulama mimarisi oluşturma konusunda yardıma ihtiyacınız varsa veya yalnızca ekibinizde uzman ön uç mühendisliği istiyorsanız geliştirme hizmetlerimizi keşfedin.
Yazan
ECOSIRE TeamTechnical Writing
The ECOSIRE technical writing team covers Odoo ERP, Shopify eCommerce, AI agents, Power BI analytics, GoHighLevel automation, and enterprise software best practices. Our guides help businesses make informed technology decisions.
ECOSIRE
ECOSIRE ile İşinizi Büyütün
ERP, e-Ticaret, yapay zeka, analitik ve otomasyon genelinde kurumsal çözümler.
İlgili Makaleler
Odoo 19 HR: Beceri Matrisi, Kariyer Planları, Performans Döngüleri
Odoo 19 İK yükseltmesi: yerel beceriler matrisi, kariyer yolu planlaması, performans inceleme döngüleri, 9 kutulu tablo, yedekleme planlaması, HRIS entegrasyonu.
Odoo 19 Performans Karşılaştırmaları: PostgreSQL 17 Ayar Numaraları
Gerçek dünya Odoo 19 performans kıyaslamaları: web istemci hızı, ORM verimi, PG17 ayarlama ayarları, bağlantı havuzu oluşturma, çalışan sayıları, ölçeklendirme eşikleri.
Odoo OWL Çerçevesi: Bileşenler, Destekler, Kancalar, Reaktivite
OWL için eksiksiz kılavuz — Odoo'nun web kütüphanesi: bileşenler, destekler, yaşam döngüsü kancaları, reaktif durum, referanslar, yuvalar, OWL'nin Odoo modüllerine entegrasyonu.
Performance & Scalability serisinden daha fazlası
Odoo 19 HR: Beceri Matrisi, Kariyer Planları, Performans Döngüleri
Odoo 19 İK yükseltmesi: yerel beceriler matrisi, kariyer yolu planlaması, performans inceleme döngüleri, 9 kutulu tablo, yedekleme planlaması, HRIS entegrasyonu.
Odoo 19 Performans Karşılaştırmaları: PostgreSQL 17 Ayar Numaraları
Gerçek dünya Odoo 19 performans kıyaslamaları: web istemci hızı, ORM verimi, PG17 ayarlama ayarları, bağlantı havuzu oluşturma, çalışan sayıları, ölçeklendirme eşikleri.
OpenClaw Maliyet Optimizasyonu ve Büyük Ölçekte Token Verimliliği
OpenClaw belirteci maliyet optimizasyonu: hızlı önbelleğe alma, model yönlendirme, yanıt önbelleğe alma, toplu API'ler ve üretim aracıları için kiracı başına maliyet korkulukları.
10 Milyon Satırdan Fazla Tablolar için Power BI Artımlı Yenileme
10 milyondan fazla satır tablosu için Power BI Artımlı Yenileme oyun kitabı: bölüm tasarımı, RangeStart/RangeEnd, yenileme ilkeleri, sorgu katlama ve DirectQuery hibritleri.
Web Kancası Hata Ayıklama ve İzleme: Eksiksiz Sorun Giderme Kılavuzu
Arıza modellerini, hata ayıklama araçlarını, yeniden deneme stratejilerini, izleme kontrol panellerini ve en iyi güvenlik uygulamalarını kapsayan bu eksiksiz kılavuzla webhook hata ayıklama konusunda uzmanlaşın.
k6 Yük Testi: Lansmandan Önce API'lerinize Stres Testi Yapın
Node.js API'leri için k6 yük testinde uzmanlaşın. Sanal kullanıcı artışlarını, eşikleri, senaryoları, HTTP/2, WebSocket testini, Grafana kontrol panellerini ve CI entegrasyon modellerini kapsar.