React'te güçlü ve modern form doğrulamanın kilidini açın. Bu kapsamlı kılavuz, sağlam ve performanslı formlar oluşturmak için experimental_useForm_Status hook'unu, sunucu eylemlerini ve durum doğrulama paradigmasını araştırıyor.
React'in `experimental_useFormStatus` Hook'u ile Form Doğrulamada Uzmanlaşma
Formlar, web etkileşiminin temel taşıdır. Basit bir bülten kaydından karmaşık, çok adımlı bir finansal başvuruya kadar, kullanıcıların uygulamalarımızla iletişim kurduğu birincil kanaldır. Yine de yıllarca React'te form durumunu yönetmek bir karmaşıklık, standart kod yığını (boilerplate) ve bağımlılık yorgunluğu kaynağı olmuştur. Kusursuz ve sezgisel bir kullanıcı deneyimi arayışında kontrollü bileşenlerle boğuştuk, durum yönetimi kütüphaneleriyle savaştık ve sayısız `onChange` işleyicisi yazdık.
React ekibi, web geliştirmenin bu temel yönünü yeniden düşünerek React Sunucu Eylemleri (React Server Actions) etrafında şekillenen yeni ve güçlü bir paradigma ortaya koydu. Aşamalı geliştirme (progressive enhancement) ilkeleri üzerine inşa edilen bu yeni model, mantığı ait olduğu yere, yani genellikle sunucuya taşıyarak form yönetimini basitleştirmeyi amaçlıyor. Bu istemci tarafı devriminin kalbinde ise iki yeni deneysel hook yatıyor: `useFormState` ve bugünkü tartışmamızın yıldızı olan `experimental_useFormStatus`.
Bu kapsamlı kılavuz, sizi `experimental_useFormStatus` hook'una derinlemesine bir yolculuğa çıkaracak. Sadece söz dizimine bakmayacağız; aynı zamanda sağladığı zihinsel modeli de keşfedeceğiz: Durum Tabanlı Doğrulama Mantığı. Bu hook'un kullanıcı arayüzünü (UI) form durumundan nasıl ayırdığını, bekleme durumlarının yönetimini nasıl basitleştirdiğini ve Sunucu Eylemleri ile birlikte çalışarak JavaScript yüklenmeden önce bile çalışan sağlam, erişilebilir ve yüksek performanslı formlar oluşturduğunu öğreneceksiniz. React'te form oluşturma hakkında bildiğinizi sandığınız her şeyi yeniden düşünmeye hazırlanın.
Bir Paradigma Değişimi: React Formlarının Evrimi
`useFormStatus`'un getirdiği yeniliği tam olarak takdir etmek için önce React ekosistemindeki form yönetimi yolculuğunu anlamalıyız. Bu bağlam, yeni yaklaşımın ne kadar zarif bir şekilde çözdüğü sorunları vurgulamaktadır.
Eski Yöntemler: Kontrollü Bileşenler ve Üçüncü Parti Kütüphaneler
Yıllarca React'te formlar için standart yaklaşım kontrollü bileşen (controlled component) deseniydi. Bu desen şunları içerir:
- Her form girdisinin değerini tutmak için bir React durum değişkeni (ör. `useState`'ten gelen) kullanmak.
- Her tuş vuruşunda durumu güncellemek için bir `onChange` işleyicisi yazmak.
- Durum değişkenini girdinin `value` prop'una geri geçirmek.
Bu, React'e formun durumu üzerinde tam kontrol sağlarken, önemli ölçüde standart kod yığını (boilerplate) ortaya çıkarır. On alana sahip bir form için on durum değişkenine ve on işleyici fonksiyona ihtiyacınız olabilir. Doğrulama, hata durumları ve gönderim durumunu yönetmek daha da fazla karmaşıklık ekler, bu da geliştiricileri genellikle karmaşık özel hook'lar oluşturmaya veya kapsamlı üçüncü parti kütüphanelere yönlendirir.
Formik ve React Hook Form gibi kütüphaneler bu karmaşıklığı soyutlayarak öne çıktı. Durum yönetimi, doğrulama ve performans optimizasyonu için harika çözümler sunarlar. Ancak, yönetilmesi gereken başka bir bağımlılığı temsil ederler ve genellikle tamamen istemci tarafında çalışırlar, bu da ön uç (frontend) ve arka uç (backend) arasında doğrulama mantığının tekrarlanmasına yol açabilir.
Yeni Dönem: Aşamalı Geliştirme ve Sunucu Eylemleri
React Sunucu Eylemleri bir paradigma değişimi sunar. Temel fikir, web platformunun temel taşı üzerine inşa etmektir: standart HTML `
Basit Bir Örnek: Akıllı Gönder Düğmesi
En yaygın kullanım senaryosunu iş başında görelim. Standart bir `
Dosya: SubmitButton.js
import { experimental_useFormStatus as useFormStatus } from 'react-dom';
export function SubmitButton() {
const { pending } = useFormStatus();
return (
);
}
Dosya: SignUpForm.js
import { SubmitButton } from './SubmitButton';
import { signUpAction } from './actions'; // Bir sunucu eylemi
export function SignUpForm() {
return (
Bu örnekte, `SubmitButton` tamamen kendi kendine yeterlidir. Herhangi bir prop almaz. `SignUpForm`'un ne zaman beklemede olduğunu bilmek için `useFormStatus`'u kullanır ve otomatik olarak kendini devre dışı bırakır ve metnini değiştirir. Bu, bileşenleri ayrıştırmak ve yeniden kullanılabilir, formdan haberdar bileşenler oluşturmak için güçlü bir desendir.
Meselenin Özü: Durum Tabanlı Doğrulama Mantığı
Şimdi temel kavrama geldik. `useFormStatus` sadece yükleme durumları için değildir; doğrulamayı farklı bir şekilde düşünmeyi sağlayan kilit bir unsurdur.
"Durum Doğrulaması"nı Tanımlama
Durum Tabanlı Doğrulama, doğrulama geri bildiriminin kullanıcıya öncelikli olarak bir form gönderme girişimine yanıt olarak iletildiği bir desendir. Her tuş vuruşunda (`onChange`) veya kullanıcı bir alanı terk ettiğinde (`onBlur`) doğrulama yapmak yerine, birincil doğrulama mantığı kullanıcı formu gönderdiğinde çalışır. Bu gönderimin sonucu—yani *durumu* (ör. başarı, doğrulama hatası, sunucu hatası)—daha sonra kullanıcı arayüzünü güncellemek için kullanılır.
Bu yaklaşım, React Sunucu Eylemleri ile mükemmel bir şekilde uyum sağlar. Sunucu eylemi, doğrulama için tek doğruluk kaynağı haline gelir. Form verilerini alır, iş kurallarınıza göre doğrular (ör. "bu e-posta zaten kullanılıyor mu?") ve sonucu belirten yapılandırılmış bir durum nesnesi döndürür.
Ortağının Rolü: `experimental_useFormState`
`useFormStatus` bize *ne* olduğunu (beklemede) söyler, ancak ne olduğunun *sonucunu* söylemez. Bunun için kardeş hook'una ihtiyacımız var: `experimental_useFormState`.
`useFormState`, bir form eyleminin sonucuna göre durumu güncellemek için tasarlanmış bir hook'tur. Eylem fonksiyonunu ve bir başlangıç durumunu argüman olarak alır ve yeni bir durum ile formunuza geçireceğiniz sarmalanmış bir eylem fonksiyonu döndürür.
const [state, formAction] = useFormState(myAction, initialState);
- `state`: Bu, `myAction`'ın son yürütülmesinden dönen değeri içerecektir. Hata mesajlarımızı buradan alacağız.
- `formAction`: Bu, `
`'un `action` prop'una geçirmeniz gereken eyleminizin yeni bir versiyonudur. Bu çağrıldığında, orijinal eylemi tetikleyecek ve `state`'i güncelleyecektir.
Birleşik İş Akışı: Tıklamadan Geri Bildirime
İşte `useFormState` ve `useFormStatus`'un tam bir doğrulama döngüsü oluşturmak için nasıl birlikte çalıştığı:
- İlk Render: Form, `useFormState` tarafından sağlanan bir başlangıç durumuyla render edilir. Hiçbir hata gösterilmez.
- Kullanıcı Gönderimi: Kullanıcı gönder düğmesine tıklar.
- Bekleme Durumu: Gönder düğmesindeki `useFormStatus` hook'u anında `pending: true` olarak raporlar. Düğme devre dışı kalır ve bir yükleme mesajı gösterir.
- Eylem Yürütme: Sunucu eylemi (`useFormState` tarafından sarmalanmış), form verileriyle yürütülür. Doğrulama gerçekleştirir.
- Eylem Geri Dönüşü: Eylem doğrulamada başarısız olur ve bir durum nesnesi döndürür, örneğin:
`{ message: "Doğrulama başarısız oldu", errors: { email: "Bu e-posta zaten alınmış." } }` - Durum Güncellemesi: `useFormState` bu dönüş değerini alır ve `state` değişkenini günceller. Bu, form bileşeninin yeniden render edilmesini tetikler.
- UI Geri Bildirimi: Form yeniden render edilir. `useFormStatus`'tan gelen `pending` durumu `false` olur. Bileşen artık `state.errors.email`'i okuyabilir ve hata mesajını e-posta giriş alanının yanında görüntüleyebilir.
Bu tüm akış, tamamen gönderim durumu ve sonucuna dayalı olarak kullanıcıya net, sunucu tarafından yetkilendirilmiş geri bildirim sağlar.
Pratik Ustalık Sınıfı: Çok Alanlı Bir Kayıt Formu Oluşturma
Bu kavramları, eksiksiz, üretim tarzı bir kayıt formu oluşturarak pekiştirelim. Doğrulama için bir sunucu eylemi ve harika bir kullanıcı deneyimi oluşturmak için hem `useFormState` hem de `useFormStatus` kullanacağız.
Adım 1: Doğrulama ile Sunucu Eylemini Tanımlama
Öncelikle, sunucu eylemimize ihtiyacımız var. Sağlam bir doğrulama için popüler Zod kütüphanesini kullanacağız. Bu eylem, Next.js gibi bir framework kullanıyorsanız `'use server';` yönergesiyle işaretlenmiş ayrı bir dosyada yer alacaktır.
Dosya: actions/authActions.js
'use server';
import { z } from 'zod';
// Doğrulama şemasını tanımla
const registerSchema = z.object({
username: z.string().min(3, 'Kullanıcı adı en az 3 karakter olmalıdır.'),
email: z.string().email('Lütfen geçerli bir e-posta adresi girin.'),
password: z.string().min(8, 'Şifre en az 8 karakter olmalıdır.'),
});
// Formumuz için başlangıç durumunu tanımla
export const initialState = {
message: '',
errors: {},
};
export async function registerUser(prevState, formData) {
// 1. Form verilerini doğrula
const validatedFields = registerSchema.safeParse(
Object.fromEntries(formData.entries())
);
// 2. Doğrulama başarısız olursa, hataları döndür
if (!validatedFields.success) {
return {
message: 'Doğrulama başarısız oldu. Lütfen alanları kontrol edin.',
errors: validatedFields.error.flatten().fieldErrors,
};
}
// 3. (Simülasyon) Kullanıcının veritabanında zaten var olup olmadığını kontrol et
// Gerçek bir uygulamada, burada veritabanınızı sorgulardınız.
if (validatedFields.data.email === 'user@example.com') {
return {
message: 'Kayıt başarısız oldu.',
errors: { email: ['Bu e-posta zaten kayıtlı.'] },
};
}
// 4. (Simülasyon) Kullanıcıyı oluştur
console.log('Kullanıcı oluşturuluyor:', validatedFields.data);
// 5. Başarı durumunu döndür
// Gerçek bir uygulamada, burada 'next/navigation'dan `redirect()` kullanarak yönlendirme yapabilirsiniz
return {
message: 'Kullanıcı başarıyla kaydedildi!',
errors: {},
};
}
Bu sunucu eylemi formumuzun beynidir. Kendi kendine yeterli, güvenli ve hem başarı hem de hata durumları için net bir veri yapısı sağlar.
Adım 2: Yeniden Kullanılabilir, Durumdan Haberdar Bileşenler Oluşturma
Ana form bileşenimizi temiz tutmak için, girdilerimiz ve gönder düğmemiz için özel bileşenler oluşturacağız.
Dosya: components/SubmitButton.js
'use client';
import { experimental_useFormStatus as useFormStatus } from 'react-dom';
export function SubmitButton({ label }) {
const { pending } = useFormStatus();
return (
);
}
`aria-disabled={pending}` kullanımına dikkat edin. Bu, ekran okuyucuların devre dışı bırakılmış durumu doğru bir şekilde anons etmesini sağlayan önemli bir erişilebilirlik uygulamasıdır.
Adım 3: Ana Formu `useFormState` ile Birleştirme
Şimdi, her şeyi ana form bileşenimizde bir araya getirelim. UI'ımızı `registerUser` eylemine bağlamak için `useFormState` kullanacağız.
Dosya: components/RegistrationForm.js
{state.message} {state.message}
{state.errors.username[0]}
{state.errors.email[0]}
{state.errors.password[0]}
'use client';
import { experimental_useFormState as useFormState } from 'react-dom';
import { registerUser, initialState } from '../actions/authActions';
import { SubmitButton } from './SubmitButton';
export function RegistrationForm() {
const [state, formAction] = useFormState(registerUser, initialState);
return (
Kaydol
{state?.message && !state.errors &&
Bu bileşen artık bildirimsel (declarative) ve temiz. `useFormState` tarafından sağlanan `state` nesnesi dışında hiçbir durumu kendisi yönetmiyor. Tek işi, bu duruma göre UI'ı render etmektir. Düğmeyi devre dışı bırakma mantığı `SubmitButton` içinde kapsüllenmiştir ve tüm doğrulama mantığı `authActions.js` dosyasında bulunur. Bu görev ayrımı, sürdürülebilirlik için büyük bir kazançtır.
İleri Teknikler ve Profesyonel En İyi Uygulamalar
Temel desen güçlü olsa da, gerçek dünya uygulamaları genellikle daha fazla incelik gerektirir. Bazı ileri teknikleri keşfedelim.
Hibrit Yaklaşım: Anlık ve Gönderim Sonrası Doğrulamayı Birleştirme
Durum tabanlı doğrulama, sunucu tarafı kontroller için mükemmeldir, ancak bir kullanıcıya e-postasının geçersiz olduğunu söylemek için bir ağ gidiş-dönüşünü beklemek yavaş olabilir. Hibrit bir yaklaşım genellikle en iyisidir:
- HTML5 Doğrulamasını Kullanın: Temelleri unutmayın! `required`, `type="email"`, `minLength` ve `pattern` gibi nitelikler, hiçbir maliyeti olmadan anında, tarayıcıya özgü geri bildirim sağlar.
- Hafif İstemci Tarafı Doğrulama: Tamamen kozmetik veya biçimlendirme kontrolleri için (ör. şifre gücü göstergesi), hala minimal miktarda `useState` ve `onChange` işleyicileri kullanabilirsiniz.
- Sunucu Tarafı Yetkisi: İstemcide yapılamayan en kritik, iş mantığı doğrulamasını (ör. benzersiz kullanıcı adlarını kontrol etme, veritabanı kayıtlarına karşı doğrulama) sunucu eylemine ayırın.
Bu size her iki dünyanın da en iyisini sunar: basit hatalar için anında geri bildirim ve karmaşık kurallar için yetkili doğrulama.
Erişilebilirlik (A11y): Herkes İçin Formlar Oluşturma
Erişilebilirlik tartışılamaz bir konudur. Durum tabanlı doğrulamayı uygularken şu noktaları aklınızda bulundurun:
- Hataları Anons Edin: Örneğimizde, hata mesajı kapsayıcılarında `aria-live="polite"` kullandık. Bu, ekran okuyuculara hata mesajı göründüğü anda, kullanıcının mevcut akışını kesmeden anons etmesini söyler.
- Hataları Girdilerle İlişkilendirin: Daha sağlam bir bağlantı için `aria-describedby` niteliğini kullanın. Girdi, hata mesajı kapsayıcısının ID'sine işaret ederek programatik bir bağlantı oluşturabilir.
- Odak Yönetimi: Hatalı bir gönderimden sonra, odağı programatik olarak ilk geçersiz alana taşımayı düşünün. Bu, kullanıcıların neyin yanlış gittiğini aramak zorunda kalmasını önler.
`useFormStatus`'un `data` Özelliği ile İyimser UI
Bir kullanıcının yorum yaptığı bir sosyal medya uygulamasını hayal edin. Bir saniye boyunca bir yükleme göstergesi göstermek yerine, uygulamayı anlık hissettirebilirsiniz. `useFormStatus`'tan gelen `data` özelliği bunun için mükemmeldir.
Form gönderildiğinde, `pending` true olur ve `data`, gönderimin `FormData`'sı ile doldurulur. Bu `data`'yı kullanarak yeni yorumu geçici, 'beklemede' olan bir görsel durumda hemen render edebilirsiniz. Sunucu eylemi başarılı olursa, bekleyen yorumu sunucudan gelen nihai veriyle değiştirirsiniz. Başarısız olursa, bekleyen yorumu kaldırabilir ve bir hata gösterebilirsiniz. Bu, uygulamanın inanılmaz derecede duyarlı hissetmesini sağlar.
"Deneysel" Sularda Gezinme
`experimental_useFormStatus` ve `experimental_useFormState`'teki "experimental" (deneysel) önekini ele almak çok önemlidir.
"Deneysel" Gerçekten Ne Anlama Geliyor
React bir API'yi deneysel olarak etiketlediğinde, bu şu anlama gelir:
- API değişebilir: Ad, argümanlar veya dönüş değerleri, standart anlamsal sürümlemeyi (SemVer) takip etmeden gelecekteki bir React sürümünde değiştirilebilir.
- Hatalar olabilir: Yeni bir özellik olarak, henüz tam olarak anlaşılmamış veya çözülmemiş uç durumları olabilir.
- Belgelendirme yetersiz olabilir: Temel kavramlar belgelenmiş olsa da, ileri düzey desenler hakkındaki ayrıntılı kılavuzlar hala gelişiyor olabilir.
Ne Zaman Benimsemeli ve Ne Zaman Beklemeli
Peki, projenizde kullanmalı mısınız? Cevap bağlamınıza bağlıdır:
- Uygun Olduğu Durumlar: Kişisel projeler, şirket içi araçlar, startup'lar veya potansiyel API değişikliklerini yönetmekte rahat olan ekipler. Next.js (bu özellikleri App Router'ına entegre eden) gibi bir framework içinde kullanmak genellikle daha güvenli bir bahistir, çünkü framework bazı değişiklikleri soyutlamaya yardımcı olabilir.
- Dikkatli Kullanılması Gereken Durumlar: API istikrarının çok önemli olduğu büyük ölçekli kurumsal uygulamalar, kritik sistemler veya uzun vadeli bakım sözleşmeleri olan projeler. Bu durumlarda, hook'ların kararlı bir API'ye yükseltilmesini beklemek akıllıca olabilir.
Bu hook'ların kararlı hale gelmesiyle ilgili duyurular için her zaman resmi React blogunu ve belgelerini takip edin.
Sonuç: React'te Formların Geleceği
`experimental_useFormStatus` ve ilgili API'lerin tanıtımı, yeni bir araçtan daha fazlasıdır; React ile etkileşimli deneyimler oluşturma şeklimizde felsefi bir değişimi temsil eder. Web platformunun temellerini benimseyerek ve durumlu mantığı sunucuda bir araya getirerek, daha basit, daha dayanıklı ve genellikle daha performanslı uygulamalar oluşturabiliriz.
Bileşenlerin bir form gönderiminin yaşam döngüsüne tepki vermesi için `useFormStatus`'un nasıl temiz, ayrıştırılmış bir yol sağladığını gördük. Bekleme durumları için prop'ların katmanlar arası aktarımını (prop drilling) ortadan kaldırır ve akıllı bir `SubmitButton` gibi zarif, kendi kendine yeterli UI bileşenleri sağlar. `useFormState` ile birleştirildiğinde, sunucunun nihai otorite olduğu ve istemcinin ana sorumluluğunun sunucu eylemi tarafından döndürülen durumu render etmek olduğu güçlü durum tabanlı doğrulama deseninin kilidini açar.
"Deneysel" etiketi bir dereceye kadar dikkat gerektirse de, yön açıktır. React'te formların geleceği, aşamalı geliştirme, basitleştirilmiş durum yönetimi ve istemci ile sunucu mantığı arasında güçlü, sorunsuz bir entegrasyondur. Bu yeni hook'larda bugün ustalaşarak, sadece yeni bir API öğrenmiyorsunuz; React ile yeni nesil web uygulaması geliştirmeye hazırlanıyorsunuz.