Modern frontend geliştirme dünyasında sunucu durumu ile istemci durumu arasındaki ayrım sadece teorik bir kavram değildir; uygulama mimarisinin omurgasıdır. Uygulamalar karmaşıklaştıkça veriyi yönetme şeklimiz performans, sürdürülebilirlik ve kullanıcı deneyimi açısından kritik hale gelir. İster React, ister Vue, isterse hibrit bir framework ile çalışıyor olun, veriyi sunucudan ne zaman çekeceğinizi ve ne zaman yerel olarak saklayacağınızı anlamak, ölçeklenebilir yazılım geliştirmenin anahtarıdır.
İki Durumun Tanımlanması
Etkili uygulamalar geliştirmek için önce her bir durum türünün neyi ifade ettiğini net bir şekilde tanımlamalıyız. Bu ayrım, hangi araçları ve desenleri kullanmamız gerektiğini belirler.
Sunucu Durumu, arka uçtan (backend) kaynaklanan verileri ifade eder. Bu, kullanıcı profilleri, ürün listeleri, kimlik doğrulama belirteçleri ve alınması veya değiştirilmesi için bir API çağrısı gerektiren herhangi bir veriyi içerir. Temel özellikleri şunlardır:
- Gecikme (Latency): Yerel değildir, bu nedenle ağ istekleri içerir.
- Önbellekleme (Caching):: Gereksiz tekrarlı isteklerden kaçınmak için önbelleğe alınmalıdır.
- Eşitleme: Birden fazla sekme veya cihaz arasında eşitlenmesi gerekebilir.
- Sahiplik: Tek doğruluk kaynağı sunucudadır.
İstemci Durumu, tarayıcı içinde bulunan ve bir API çağrısı gerektirmeyen verileri ifade eder. Bu, aktif sekme kimlikleri, modal açma/kapama geçişleri, form giriş değerleri ve tema tercihleri gibi UI durumlarını içerir. Temel özellikleri şunlardır:
- Gecikme (Latency): Yereldir, bu nedenle erişim anlıktır.
- Eşitleme: Bir arka uç sunucusuyla eşitlenmesi gerekmez.
- Sahiplik: Durum geçicidir ve mevcut oturuma bağlıdır.
Sunucu Verisi İçin Global Durum Kullanmanın Tuzağı
Redux'tan yeni çözümlere geçiş yapan geliştiriciler arasında özellikle yaygın olan yaygın bir anti-pattern (ters desen), sunucu durumunu global istemci durumu gibi işlemektir. Redux, Vuex veya Pinia gibi araçları API yanıtlarını önbelleğe almak için kullanmak genellikle gereksiz kod yazılmasına yol açar. Zaten özel kütüphanelerde bulunan yükleme durumları, hata yönetimi ve önbellek geçersiz kılma için iskelet kod (boilerplate) yazmakla karşı karşıya kalırsınız.
Örneğin, bir kullanıcı listesi görüntüleyen bir bileşeni düşünün. Bu listeyi global istemci durumuna depolarsanız, asenkron yaşam döngüsünü manuel olarak yönetmek zorunda kalırsınız:
// Anti-pattern: Sunucu durumunun manuel istemci tarafı yönetimi
useEffect(() => {
const fetchUsers = async () => {
setUsersLoading(true);
try {
const response = await fetch('/api/users');
const data = await response.json();
setUsers(data);
} catch (error) {
setUsersError(error);
} finally {
setUsersLoading(false);
}
};
fetchUsers();
}, []);
Bu yaklaşım kötü ölçeklenir. Başka bir bileşenin de aynı kullanıcı verisine ihtiyacı olursa, mantığı kopyalamak zorunda kalırsınız veya karmaşık seçiciler (selectors) oluşturursunuz; bu da prop-drilling'e (prop yığılması) ve sıkı bağlılığa (tight coupling) yol açar.
Çözüm: Sunucu Durumu İçin Özel Araçlar
Modern ekosistem, sunucu durumunu yönetmek için özel olarak tasarlanmış kütüphaneler sağlar. React ekosisteminde React Query (TanStack Query) standart haline gelmiştir. Vue ekosisteminde ise Vue Query veya yerel composition API'lerle eşleştirilmiş Orval benzeri roller üstlenir.
Bu kütüphaneler önbellekleme, arka plan yeniden çekme (refetching) ve istek eşzamanlılığını (deduplication) kutudan çıkar (out of the box) şekilde halleder. React Query kullanılarak yazılmış bir React bileşeni şöyle görünebilir:
// En İyi Uygulama: Sunucu durumu için React Query kullanımı
import { useQuery } from '@tanstack/react-query';
function UserList() {
const { data, isLoading, error } = useQuery({
queryKey: ['users'],
queryFn: () => fetch('/api/users').then(res => res.json())
});
if (isLoading) return <div>Yükleniyor...</div>;
if (error) return <div>Bir hata oluştu: {error.message}</div>;
return (
<ul>
{data.map(user => (
<li key={user.id}>{user.name}</li>
))}
</ul>
);
}
Bu çözüm bildirimseldir (declarative), özündür ve önbellekleme ile eşitlemeyi otomatik olarak halleder.
Sonuç: Basit Tutun, Yerel Tutun
Altın kural basittir: Veri sunucudan geliyorsa bir sunucu durumu yönetim kütüphanesi kullanın. Veri UI ile ilgiliyse ve tarayıcıda kalıyorsa yerel bileşen durumunu, context'i veya Redux veya Pinia gibi global bir istemci deposunu kullanın. Sunucu ve istemci durumu arasındaki sınırlara saygı duyarak iskelet kodu azaltır, performansı artırır ve bakımı daha kolay uygulamalar geliştirirsiniz. Doğru iş için doğru aracı seçin, mimariniz size teşekkür edecektir.