Bei der Arbeit mit Next.js ist einer der häufigsten Fehler, der auftreten kann, der Fehler „Hydratation failed“. Ich werde erklären, warum dieser Fehler auftritt und wie man ihn beheben kann.
The Reason #
This error is caused by one of the React's apis called hydrateRoot
. This api is used to attach React to the pre-rendered HTML usually generated by the server (react-dom/server) for adding interactivity to (in most cases). The reason why you see it in a Next.js compiled react app is lying here. Since Next.js renders components on server side (SSR), it uses hydrateRoot
api under the hood. When a user visits your site Next.js or other frameworks such as Gatsby or Astro (frameworks that allows server side rendering) serve the user with a statically generated html page. Then, hydrateRoot
api attaches all of the effects, state and/or event listeners to this page. While hydrating React expects the this rendered content to be same with the server-rendered content.
Der Grund #
Dieser Fehler wird durch eine der React-APIs namens hydrateRoot
verursacht. Diese API wird verwendet, um React an den vorgerenderten HTML-Code anzuhängen, der normalerweise vom Server (react-dom/server) generiert wird, um (in den meisten Fällen) Interaktivität hinzuzufügen. Der Grund, warum Sie es in einer mit Next.js kompilierten Reaktions-App sehen, liegt hier. Da Next.js Komponenten auf der Serverseite (SSR) rendert, verwendet es unter der Haube die hydrateRoot
api. Wenn ein Benutzer Ihre Website besucht, stellen Next.js oder andere Frameworks wie Gatsby oder Astro (Frameworks, die serverseitiges Rendern ermöglichen) dem Benutzer eine statisch generierte HTML-Seite zur Verfügung. Anschließend fügt die HydrateRoot-API alle Effekte, Status- und/oder Ereignis-Listener an diese Seite an. Während der Hydratation geht React davon aus, dass dieser gerenderte Inhalt mit dem vom Server gerenderten Inhalt übereinstimmt.
Mögliche Szenarien, die den Fehler "Hydratation Failed“ verursachen #
Vor diesem Hintergrund sind hier einige Gründe aufgeführt, warum dieser Fehler in realen Szenarien auftreten kann.
- Wenn Sie Ihre HTML-Tags falsch verschachtelt haben. Zum Beispiel; wenn Sie ein
<a></a>
-Tag innerhalb eines<span></span>
-Tags verschachtelt haben. Während das clientseitige Rendering mit einer fehlerhaften Verschachtelung von HTML-Tags funktionieren kann, da die DOM-API es Ihnen ermöglicht, diese Tags manuell zu erstellen, ist es Ihnen unmöglich, HTML-Tags in einer serverseitig gerenderten HTML-Seite zu verschachteln. Die DOM-API analysiert es nicht einfach. Hier lässt sich der Schluss ziehen, dass einige der gängigen Komponentenbibliotheken wie Material Ui und Ant Desgin falsch verschachtelte HTML-Komponenten enthalten. Daher können diese Komponenten der Grund dafür sein, dass Sie diesen Fehler erhalten. - Wenn Sie versuchen, browserbasierte APIs wie
localStorage
,sessionStorage
oderwindow
in Ihrer Rendering-Logik zu verwenden. Dies kann das Problem verursachen, da Ihr SSR-HTML beim ersten Rendern keinen Zugriff auf die Browser-APIs hat. - Eine Bibliothek, die unter der Haube versucht, das oben Genannte zu tun.
- Clientseitige Logik in der Renderphase. In meinem neuesten Projekt war es meine
ThemeSwitcher-Komponente
, die versuchte, die Renderlogik mit einem clientseitigen Status zu verändern.
Ich kann Sie sagen hören, dass diese Komponente „Client verwenden“ hat und daher clientseitig gerendert wird. Du hast Recht. Obwohl diese Komponente auf der Clientseite gerendert wird, wird sie von Next.js dennoch auf der Serverseite hydriert.
Wie man es löst #
1. Sie können den Fehler grundsätzlich unterdrücken.
Dies löst Ihr Problem, wenn Sie Abstriche machen und diesen Fehler mutieren möchten.
2. Verwendung des useEffect
Hooks
Stellen Sie sicher, dass die Komponente beim serverseitigen Rendern und in den ersten clientseitigen Renderingphasen denselben Inhalts-Bot rendert. Auf diese Weise können Sie einem Flüssigkeitsmangel vorbeugen. Dazu habe ich eine HydrateWrapper-Komponente
erstellt, die beim ersten Rendern den Loader zurückgibt, sodass Client und Server übereinstimmen, um Hydratationsfehler
durch UI-Updates zu verhindern.
Wickeln Sie dann Ihre Komponenten mit dieser Komponente ein.
3. Sie können SSR einfach für bestimmte Komponenten deaktivieren
Zusammenfassung #
Während Next.js und andere Reaktionsframeworks wie Gatsby
und Astro
versuchen, serverseitig gerenderte statische Seiten mithilfe von hydrateRoot
zu hydratisieren, wird möglicherweise eine Hydratationswarnung ausgegeben. Wenn die ursprüngliche Benutzeroberfläche nicht mit dem übereinstimmt, was auf dem Server gerendert wurde, d. h., dass sich das anfängliche SSR-HTML von der anfänglichen React-Render-Logik unterscheidet, wird ein Fehler ausgegeben. Sie können es einfach unterdrücken, mit useEffect überwinden oder SSR deaktivieren. Wenn Sie eine Idee haben, auf dieses Problem gestoßen sind oder Feedback zu meinem Artikel haben, hinterlassen Sie bitte unten einen Kommentar. Danke fürs Lesen.