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.
İlgili Makaleler
k6 Load Testing: Stress-Test Your APIs Before Launch
Master k6 load testing for Node.js APIs. Covers virtual user ramp-ups, thresholds, scenarios, HTTP/2, WebSocket testing, Grafana dashboards, and CI integration patterns.
Next.js 16 App Router: Production Patterns and Pitfalls
Production-ready Next.js 16 App Router patterns: server components, caching strategies, metadata API, error boundaries, and performance pitfalls to avoid.
Odoo Performance Tuning: PostgreSQL and Server Optimization
Expert guide to Odoo 19 performance tuning. Covers PostgreSQL configuration, indexing, query optimization, Nginx caching, and server sizing for enterprise deployments.
Performance & Scalability serisinden daha fazlası
k6 Load Testing: Stress-Test Your APIs Before Launch
Master k6 load testing for Node.js APIs. Covers virtual user ramp-ups, thresholds, scenarios, HTTP/2, WebSocket testing, Grafana dashboards, and CI integration patterns.
Nginx Production Configuration: SSL, Caching, and Security
Nginx production configuration guide: SSL termination, HTTP/2, caching headers, security headers, rate limiting, reverse proxy setup, and Cloudflare integration patterns.
Odoo Performance Tuning: PostgreSQL and Server Optimization
Expert guide to Odoo 19 performance tuning. Covers PostgreSQL configuration, indexing, query optimization, Nginx caching, and server sizing for enterprise deployments.
Odoo vs Acumatica: Cloud ERP for Growing Businesses
Odoo vs Acumatica compared for 2026: unique pricing models, scalability, manufacturing depth, and which cloud ERP fits your growth trajectory.
Testing and Monitoring AI Agents in Production
A complete guide to testing and monitoring AI agents in production environments. Covers evaluation frameworks, observability, drift detection, and incident response for OpenClaw deployments.
Compliance Monitoring Agents with OpenClaw
Deploy OpenClaw AI agents for continuous compliance monitoring. Automate regulatory checks, policy enforcement, audit trail generation, and compliance reporting.