I'm always excited to take on new projects and collaborate with innovative minds.
Kayseri/Turkey
Bu yazıda, React’ta useSyncExternalStore kancası ile hydration uyumsuzluklarını nasıl önleyebileceğimizi, aynı zamanda Suspense ve useDeferredValue kombinasyonuyla bu süreci nasıl daha sorunsuz hale getirebileceğimizi anlatacağım.
Hydration, React’ın sunucu tarafında oluşturulan HTML çıktısını tarayıcıda interaktif bileşenlerle eşleştirmesi sürecidir.
Yani sayfa ilk açıldığında, kullanıcı aslında statik bir HTML görür. Ardından React bu yapıyı “canlandırır” ve butonlar, inputlar gibi etkileşimli hale getirir.
Ancak bazen sunucuda render edilen HTML ile istemcide oluşturulan React ağacı birebir uyuşmaz. Bu durumda React “hydration mismatch” hatası verir veya bileşeni yeniden render etmek zorunda kalır.
useSyncExternalStore
Nedir?useSyncExternalStore
, React’ın 18 sürümüyle birlikte eklenen bir hook’tur.
Dış veri kaynaklarıyla (örneğin global store, event emitter, vs.) SSR + hydration uyumlu bir şekilde çalışmayı sağlar.
Temel kullanımı şöyle görünür:
const isSSR = React.useSyncExternalStore(
() => () => {}, // subscribe: değişiklikleri dinler
() => false, // getSnapshot: istemci tarafında çağrılır
() => true // getServerSnapshot: sunucu + hydration sırasında çağrılır
)
Bu yapı sayesinde React, sunucu ve istemci tarafındaki çıktılar arasında eşitlik sağlar.
Yani hydration sırasında ne bekleniyorsa, o değer döner — böylece mismatch oluşmaz.
useSyncExternalStore
ve Suspense Arasındaki TuzaklaruseSyncExternalStore
harika bir çözüm gibi görünse de, özellikle bileşeniyle birlikte kullanıldığında bazı problemler ortaya çıkar:
useSyncExternalStore
eşzamanlı render tetiklediği için ana iş parçacığını bloke eder. Bu, etkileşimlerde gecikme yaratır.useDeferredValue
ile Birlikte KullanmakBu sorunları çözmek için useDeferredValue
hook’u devreye giriyor.
Yani useSyncExternalStore
’dan dönen değeri ertelenmiş bir şekilde yöneterek, hem hydration uyumsuzluklarını hem de performans sorunlarını önleyebiliriz.
İşte örnek uygulama:
const emptySubscribe = () => () => {}
const returnFalse = () => false
const trueOnServerOrHydration = () => true
function useIsSSR() {
const isSSRSync = React.useSyncExternalStore(
emptySubscribe,
returnFalse,
trueOnServerOrHydration
)
return React.useDeferredValue(isSSRSync)
}
function App() {
const isSSR = useIsSSR()
return isSSR ? "Server output" : "Client output"
}
SSR + hydration
aşaması) isSSR
değeri true
olur.isSSRSync = false
değerini üretir.useDeferredValue
, bu değişimi hemen yansıtmaz → kullanıcı “yanıp sönen fallback” görmez.Sonuç olarak:
Ek olarak, yazıda useMemoOne
gibi araçlarla bileşenlerin referanslarının sabit tutulması öneriliyor.
Bu, Suspense sınırları arasında gereksiz yeniden render’ları önleyerek performansı artırır.
React’ta SSR ve hydration süreçleri, kullanıcıya hızlı ve sorunsuz bir ilk yükleme deneyimi sunmak için kritik öneme sahiptir.useSyncExternalStore
, bu süreci kontrol altına almak için güçlü bir araçtır — ancak doğru kullanılmadığında performans sorunlarına yol açabilir.
En iyi yaklaşım, bu hook’u useDeferredValue
ile birlikte kullanmaktır.
Bu sayede hem hydration hatalarından kurtulabilir hem de daha akıcı bir kullanıcı deneyimi elde edebilirsin.
E-posta hesabınız yayımlanmayacak. Gerekli alanlar işaretlendi *