Next.js ile çalışırken karşılaşabileceğiniz en yaygın hatalardan biri, hydration failed hatasıdır. Bu yazımda, hatanın neden oluştuğunu ve çözüm yollarını anlatacağım.
Sebep #
Bu hataya React'in apilerinden biri olan hydrateRoot
adlı api neden olmaktadır. Bu api, React'i (çoğu durumda) interaktiflik eklemek için genellikle sunucu (react-dom/server) tarafından oluşturulan önceden oluşturulmuş HTML'ye eklemek için kullanılır. Next.js ile derlenmiş bir react uygulamasında bunu görmenizin nedeni budur. Next.js komponentleri sunucu tarafında (SSR - server-side-rendering) oluşturduğundan, arka planda hydrateRoot api'sini kullanır. Bir kullanıcı sitenizi ziyaret ettiğinde Next.js veya Gatsby veya Astro gibi diğer frameworkler (server side rendering sağlayan frameworkler) kullanıcıya statik olarak oluşturulmuş bir html sayfası sunar. Ardından, hydrateRoot
api tüm efektleri, state ve/veya event listenerları bu sayfaya ekler. React ui'i hydrate ederken uida render edilen içeriğin sunucu tarafından render edilen içerikle aynı olmasını bekler.
Hydration Failed Hatasına Neden Olan Olası Senaryolar #
Bu fikir akılda tutularak, bu hatanın gerçek hayat senaryolarında ortaya çıkmasının nedenlerinden bazıları aşağıda verilmiştir.
- Html etiketlerinizi yanlış nest ettiyseniz. Örneğin;
<span></span>
etiketinin içine bir<a></a>
etiketi yerleştirdiyseniz bu hataya sebep olacaktır. DOM api bu tagleri manuel olarak oluşturmanıza izin verdiği için client tarafında, html etiketlerinin hatalı şekilde iç içe yerleştirilmesiyle çalışabilirken, html etiketlerini yanlış nest ederek sunucu tarafında oluşturulan bir html sayfasın render etmek imkansızdır. DOM api hatalı htmli parse edemez. Burada, Material Ui ve Ant Desgin gibi bazı yaygın komponent kütüphanelerinin uygunsuz iç içe yerleştirilmiş html bileşenlerine sahip olduğunu, dolayısıyla bu hatayı almanızın nedeni bu bileşenler olabileceği sonucuna varmak doğru bir çıkarım olacaktır. - Eğer render senaryonuzda localStorage, sessionStorage veya window gibi tarayıcı tabanlı apiler kullanmaya çalışırsanız. SSR HTML'nizin ilk render sırasında tarayıcı apilerine erişimi olmayacağı için soruna neden olabilir.
- Yukarıdakileri kaputun altında yapmaya çalışan bir kütüphane.
- Render aşamasında client side senaryosu. Son projemde, render senaryomda client side ile renderı update olan
ThemeSwitcher
komponentimdi.
Bu bileşenin "use client"
özelliğine sahip olduğunu, dolayısıyla istemci tarafında işlendiğini söylediğinizi duyar gibiyim. Haklısınız. Ancak, komponent istemci tarafında oluşturulmuş olsa da Next.js yine de bu komponenti sunucu tarafında hydrate eder.
Nasıl Çözülür #
1. Temel olarak hatayı bastırabilirsiniz.
Eğer işin kolayına kaçmak ve bu hatayı bastırmak istiyorsanız bu sorununuzu çözer.
2. useEffect
Hookunu Kullanarak
Komponenti sunucu tarafı oluşturma ve ilk client tarafında oluşturma aşamalarında aynı içeriği oluşturduğundan emin olun. Bunu yaparak hydrate uyuşmazlığını önleyebilirsiniz. Bunu yapmak için ilk renderda loader render eden bir HydrateWrapper
komponenti oluşturdum, böylece ui güncellemelerinin neden olduğu hidrasyon hatasını önlemek için istemci ve sunucu eşleşti.
Ardından hydrate hatası verecek komponentinizi bu komponente sarın.
3. Belirli komponentlerde SSR'i devre dışı bırakabilirsiniz.
Özet #
Next.js, Gatsby ve Astro gibi diğer react framework'leri, hydrateRoot
kullanarak sunucu tarafında işlenen statik sayfaları hydrate etmeye çalışırken, hydration failed uyarısı verebilir. İlk kullanıcı arayüzü sunucuda render edilenle eşleşmediğinde, başka bir deyişle sunucu tarafında render edilen html ile initial react render farklı olduğunda hata verir. Bunu kolayca bastırabilir, useEffect ile üstesinden gelebilir veya SSR'i devre dışı bırakabilirsiniz. Herhangi bir fikriniz varsa, bu sorunla karşılaştıysanız veya makalem hakkında geri bildiriminiz varsa lütfen aşağıya bir yorum bırakın. Okuduğunuz için teşekkürler.