Hjem
» Basis viden
»
Sådan løser du fejl i hydrering, fordi den oprindelige UI ikke matcher
Sådan løser du fejl i hydrering, fordi den oprindelige UI ikke matcher
Det ønskede resultat er enkelt at beskrive: Den HTML, der genereres på serveren, skal matche det, React genererer ved browserens første rendering. Når dette er tilfældet, kan React tilknytte hændelsesbehandlere og gøre siden interaktiv uden at udløse en hydreringsfejl, erstatte en undertree eller vise et uventet visuelt spring.
Hydrering er processen, hvor React tager HTML, der allerede er renderet på serveren, og tilføjer React-adfærd til den i browseren. Reacts nuværende dokumentation for hydrateRoot angiver, at klient-renderet indhold forventes at være identisk med server-renderet indhold, og at uoverensstemmelser skal behandles som fejl.
Den præcise formulering af fejlen har ændret sig på tværs af React- og framework-udgivelser. Du kan se en ældre besked som "Hydration failed because the initial UI does not match what was rendered on the server", eller en nyere besked, der forklarer, at server-renderet træ ikke matchede klienten. Fejlsøgningsprincippet er det samme.
Versionskontekst er vigtig. Pr. 11. september 2026 lister den officielle React-side React 19.3 som den seneste React-version, mens den aktuelle Next.js-dokumentation identificerer Next.js 16.3.4 som den seneste Next.js-udgivelse. Tjek Reacts versions-side og den aktuelle Next.js-dokumentation, hvis du læser dette senere, da tilgængelige API'er og fejlbeskeder kan ændre sig.
AI-genereret illustration: Start med at lokalisere den første komponent, der nævnes i hydreringsfejlen, og bekræft, at problemet opstår ved en frisk sideindlæsning. Dette er ikke et faktiskt browser-, React- eller Next.js-skærmbillede; brug de verificerede kode- og dokumentationslinks i artiklen som sandhedskilde.
Hvad tæller som en vellykket løsning?
Døm ikke succes kun ud fra, om en rød udviklingsoverlay forsvinder. En god løsning skal opfylde flere tjek:
Hydreringsadvarslen eller -fejlen vises ikke længere ved en ren genindlæsning.
Den oprindelige server-renderede UI og browserens første React-rendering repræsenterer samme indhold og struktur.
Den berørte komponent forbliver interaktiv efter hydrering.
Der er ingen åbenlys flimmer fra én værdi til en anden, medmindre ændringen er tilsigtet og designet.
Problemet forbliver løst i en produktionsbuild, ikke kun i udviklingsserveren.
Du har rettet årsagen frem for at skjule en reel uoverensstemmelse med en undertrykkelsesmulighed for advarsler.
Hvis advarslen forsvinder, men siden nu kun renderer vigtigt indhold, efter JavaScript er indlæst, kan fejlen være væk, mens brugeroplevelsen er blevet værre. Det kan være et rimeligt kompromis for en browser-afhængig widget, men det er ikke automatisk det bedste resultat for primært sideindhold.
Trin 1: Replikér uoverensstemmelsen og find den mindste fejlende komponent
Start med en hård genindlæsning i udviklingsmiljøet og læs hele fejlen, inklusive komponentstakken. Reacts 19-version dokumenterede hydreringsfejl lister flere almindelige årsager: server/klient-grene som typeof window !== 'undefined', ændrende værdier som Date.now() eller Math.random(), lokalafhængig datoformatering, eksterne data, der er ændret uden et snapshot, ugyldig HTML-nestning og browserudvidelser, der ændrer DOM'en. Se React-fejl 418.
Next.js giver en lignende liste i sin officielle guide til hydreringsfejl, hvor der tilføjes browser-afhængige API'er som window og localStorage, CSS-in-JS-konfiguration og HTML ændret af et Edge/CDN-lag.
AI-genereret illustration: Indsnævr fejlen til det udtryk, der kan producere en anden værdi på serveren og i browseren, såsom en dato, et tilfældigt tal, en lokalitet eller en browser-afledt værdi. Dette er ikke et faktiskt browser-, React- eller Next.js-skærmbillede; brug de verificerede kode- og dokumentationslinks i artiklen som sandhedskilde.
En praktisk isoleringsmetode er midlertidigt at erstatte mistænkelige dynamiske sektioner med deterministisk tekst. Hvis fejlen forsvinder, gendanner du disse sektioner én ad gangen. Dette er normalt hurtigere end at ændre globale renderingsindstillinger, før du ved, hvilken komponent der er ansvarlig.
Kvalitetssignal
Du er klar til at gå videre, når du kan navngive både den fejlende komponent og den værdi eller struktur, der adskiller sig. "Det sker et sted i dashboardet" er stadig for bredt. "Tidsstemplet i StatusCard produceres uafhængigt på serveren og klienten" er handlingsorienteret.
Trin 2: Fjern ikke-deterministiske værdier fra den oprindelige rendering
Deterministisk rendering betyder, at de samme input producerer den samme oprindelige UI. Værdier, der ændrer sig uafhængigt mellem server-rendering og browser-rendering, er hyppige kilder til uoverensstemmelser.
Overvej dette problematiske mønster:
export default function LastUpdated() {
return <time>{new Date().toLocaleString()}</time>;
}
Serveren og browseren kan køre denne kode på forskellige tidspunkter og i forskellige lokaliteter eller tidszoner. En bedre løsning afhænger af, hvad siden skal kommunikere.
Hvis tidsstemplet repræsenterer serverdata, beregn eller hent det én gang på serveren og send den samme serialiserede værdi til klienten:
Hvis værdien genuint afhænger af brugerens browser, skal du render en stabil pladsholder først og opdatere den efter hydrering.
AI-genereret illustration: En stabil oprindelig værdi kan hydrere rent, hvorefter browser-specifikt indhold kan anvendes, efter komponenten er monteret. Dette er ikke et faktiskt browser-, React- eller Next.js-skærmbillede; brug de verificerede kode- og dokumentationslinks i artiklen som sandhedskilde.
Dette virker, fordi serveren og den første klient-rendering begge producerer den samme pladsholder. Reacts useEffect-dokumentation beskriver dette to-trins mønster for de sjældne tilfælde, hvor klientindhold skal adskille sig fra serverindhold.
Hvornår du skal ændre tilgang
Hvis den browser-afhængige værdi er hele formålet med komponenten – for eksempel en editor gendannet fra localStorage eller en widget, der ikke kan rendere meningsfuldt på serveren – kan det at tvinge et pladsholder-og-effect-mønster gennem hele komponenten tilføje unødvendig kompleksitet. I så fald skal du bruge en bevidst browser-afhængig grænse frem for at lade som om, komponenten er server-renderbar.
Trin 3: Læs ikke browser-afhængige API'er under den første server-kompatible rendering
En almindelig misforståelse i Next.js er, at tilføjelse af 'use client' garanterer, at komponenten kun renderes i browseren. Det gør den ikke. Next.js forklarer, at Client Components er grænsen for state, effekter, hændelsesbehandlere og browser-API'er, men Client Components kan stadig deltage i forudrendering. Se den aktuelle use client-dokumentation.
På serveren eksisterer localStorage ikke. Selv en gren som typeof window !== 'undefined' kan producere forskellig markup ved den første browser-rendering, hvilket både React og Next.js dokumenterer som en årsag til hydreringsfejl.
For små forskelle skal du flytte browser-læsningen til en Effect. For en komponent, der virkelig skal være browser-afhængig i Next.js, kan du dynamisk indlæse den med SSR deaktiveret:
AI-genereret illustration: Brug en klient-afhængig grænse for komponenter, der fundamentalt afhænger af browser-API'er, frem for at lade serveren og browseren render forskellige træer. Dette er ikke et faktiskt browser-, React- eller Next.js-skærmbillede; brug de verificerede kode- og dokumentationslinks i artiklen som sandhedskilde.
Next.js dokumenterer ssr: false for Client Components i sin guide til lazy loading. Samme guide angiver, at ssr: false ikke understøttes, når du prøver at bruge den mulighed direkte i en Server Component; flyt det dynamiske import ind i en Client Component.
React 19.3: En førsteklasses browser-afhængig mulighed
React 19.3 introducerede browser-API'en. En komponent kan kalde use(browser()) inde i en Suspense-grænse for at fravælge server-rendering for den komponent. Serveren render Suspense-fallbacken, mens komponenten render normalt i browseren. Se Reacts browser API-reference.
import { Suspense, use } from 'react';
import { browser } from 'react-dom';
function BrowserOnlyContent() {
use(browser('Requires browser APIs'));
return <ActualBrowserContent />;
}
export default function Example() {
return (
<Suspense fallback={<p>Loading...</p>}>
<BrowserOnlyContent />
</Suspense>
);
}
I en React Server Components-applikation siger React, at use(browser()) skal kaldes fra en Client Component. Verificer også, at dit framework og den installerede React-version eksponerer denne API, før du adopterer den.
Trin 4: Gør serverdata og de første klientdata til det samme snapshot
Et snapshot er den præcise datastand, der bruges til at producere den oprindelige HTML. Hydrering bliver skrøbelig, hvis serveren render én dataversion, og klienten straks læser en nyere eller anderledes sorteret version, før hydreringen er fuldført.
AI-genereret illustration: Den første klient-rendering skal forbruge det samme oprindelige datasnapshot, der producerede server-HTML'en; senere opdateringer kan ske efter hydrering. Dette er ikke et faktiskt browser-, React- eller Next.js-skærmbillede; brug de verificerede kode- og dokumentationslinks i artiklen som sandhedskilde.
For eksempel, antag at serveren render en pris på $99, men klienten henter straks det samme produkt og får $109 før sin første rendering. Problemet er ikke, at dataene ændrede sig; ændrende data er normalt. Problemet er, at de to miljøer brugte forskellige oprindelige input.
Et stærkt mønster er:
Hent de oprindelige data på serveren.
Render HTML'en fra disse data.
Send eller serialiser de samme oprindelige data til klientkomponenten.
Tillad klienten at revalidere og opdatere, hvis nyere data eksisterer, efter hydrering.
Den korrekte implementering afhænger af dit frameworks datahentningsmodel, men kvalitetskriteriet forbliver det samme: Server-HTML'en og det første klienttræ skal baseres på den samme logiske tilstand.
Hvornår du skal ændre tilgang
Hvis indholdet er iboende realtids, og et forældet server-snapshot ville vildlede brugere – for eksempel en live-handelswidget eller en hurtigt ændrende operationskonsol – så overvej at render en stabil skal på serveren og indlæse den live-sektion på klienten. Det giver afkald på noget server-renderet indhold for den region, men det kan være mere ærligt end at hydrere mod data, der er garanteret at ændre sig.
Trin 5: Ret ugyldig HTML, før du skylder på React
Browsere har lov til at korrigere misdannet eller ugyldigt nestet HTML. Den korrektion kan producere en DOM-struktur, der adskiller sig fra den struktur, React forventer, selv når JSX'en så visuelt plausibel ud.
AI-genereret illustration: Tjek semantisk HTML-nestning, når komponenttræet ser deterministisk ud, men browseren stadig konstruerer en anden DOM. Dette er ikke et faktiskt browser-, React- eller Next.js-skærmbillede; brug de verificerede kode- og dokumentationslinks i artiklen som sandhedskilde.
Next.js nævner eksplicit eksempler som en <div> inde i et <p>, en liste inde i et afsnit, nestede anker-tags og nestede knapper som årsager til hydreringsproblemer.
For eksempel, undgå:
<p>
Intro text
<div>Details</div>
</p>
Brug i stedet en gyldig struktur:
<div>
<p>Intro text</p>
<div>Details</div>
</div>
Hvis et komponentbibliotek genererer markuppen, skal du inspicere den endelige DOM frem for at antage, at wrapper-elementerne er gyldige. En lint-regel eller HTML-validator kan hjælpe, men browserens faktiske DOM er det, React hydrerer.
Trin 6: Udeluk kode uden for komponenten
Hvis din render-logik er deterministisk, og din HTML er gyldig, så tjek om noget ændrer server-HTML'en, før React hydrerer den.
Officiel Next.js-dokumentation nævner flere muligheder:
En browserudvidelse ændrer siden, før React indlæses.
Et CSS-in-JS-bibliotek er konfigureret forkert til serverrendering.
En Edge- eller CDN-funktion omskriver eller minimerer HTML-svaret.
På iOS kan automatisk detektion af telefonnumre, e-mailadresser, datoer eller adresser ændre tekst til links i nogle tilfælde.
Brug kontrollerede sammenligninger. Test i et privat browservindue med udvidelser deaktiveret. Hvis fejlen kun opstår bag et CDN, så sammenlign med oprindelsessvaret. Hvis det startede efter adoption af et styling-bibliotek, så følg det biblioteks officielle SSR-konfiguration frem for at anvende en generisk hydrerings-workaround.
Kvalitetssignal
Du har isoleret denne klasse af problem, når den samme applikationsbuild hydrerer korrekt i ét kontrolleret miljø, men fejler efter en specifik browserudvidelse, proxy, CDN-transformation eller integration ændrer HTML'en.
Trin 7: Brug kun suppressHydrationWarning for en virkelig uundgåelig lokal forskel
React tilbyder suppressHydrationWarning={true} for sjældne tilfælde, hvor teksten eller attributterne for et enkelt element ikke rimeligt kan matche, såsom visse tidsstempler.
Dette er ikke en generel repareringsmekanisme. Reacts dokumentation for almindelige DOM-props siger, at muligheden kun virker ét niveau dybt og er tiltænkt som en udvej. Next.js-hydreringsguiden advarer også om, at React ikke vil forsøge at lappe mismatchet tekstindhold, når denne mulighed bruges.
Brug den kun, når alle disse er sande:
Forskellen er forventet og lokaliseret.
Uoverensstemmelsen repræsenterer ikke forkert applikationstilstand.
Den omgivende struktur er stabil.
Du har bevidst accepteret, at den oprindelige serverværdi og browserværdien adskiller sig.
Hvis tilføjelse af prop'en får dusinvis af advarsler til at forsvinde, er det en grund til at undersøge yderligere, ikke et tegn på, at det underliggende problem er løst.
Trin 8: Verificer løsningen i udviklings- og produktionsmiljø
AI-genereret illustration: Efter ændring af koden, verificer en ren genindlæsning, korrekt interaktivitet og en produktionsbuild i stedet for kun at stole på udviklingsoverlayen. Dette er ikke et faktiskt browser-, React- eller Next.js-skærmbillede; brug de verificerede kode- og dokumentationslinks i artiklen som sandhedskilde.
Udviklingsadfærd kan adskille sig fra en optimeret produktionsbuild. Efter fejlen er væk lokalt, udfør et produktionslignende tjek for dit framework. For et typisk Next.js-projekt betyder det ofte at bygge og starte applikationen med dine normale pakkehåndteringskommandoer, og derefter foretage friske navigationer og genindlæsninger.
Brug denne verificeringscheckliste:
Tjek
Godt tegn
Hvis det fejler
Frisk genindlæsning
Ingen hydreringsfejl i konsollen
Tjek den tidligste afvigende komponent igen
Oprindelig visuel tilstand
Intet utilsigtet flimmer eller udskiftning
Gør den oprindelige tilstand deterministisk
Interaktioner
Knapper, formularer, menuer og state fungerer normalt
Bekræft at komponenten stadig hydrerer og hændelsesbehandlere tilknyttes
Produktionsbuild
Samme korrekte resultat som i udvikling
Undersøg produktionskun data, CDN, CSS eller optimeringsadfærd
Udvidelser deaktiveret
Resultatet er uændret
Identificer DOM-ændrende udvidelsesadfærd
Hvis du direkte ejer React SSR-entrypointet i stedet for at bruge et framework, understøtter hydrateRoot også fejl-callbacks som onRecoverableError, hvilket kan hjælpe med produktionslogning. Framework-brugere bør generelt ikke erstatte frameworkets hydrerings-entrypoint kun for at tilføje custom håndtering.
Hvornår du skal prøve en anden renderingsstrategi
AI-genereret illustration: Ændr strategi, når en komponent fundamentalt ikke kan producere meningsfuld server-HTML, men hold den klient-afhængige grænse så lille som praktisk. Dette er ikke et faktiskt browser-, React- eller Next.js-skærmbillede; brug de verificerede kode- og dokumentationslinks i artiklen som sandhedskilde.
Nogle gange er den bedste løsning ikke at tvinge en komponent ind i SSR. Overvej en anden renderingsstrategi, når:
Komponenten er bygget omkring window, canvas, WebGL, browsermålinger eller en anden browser-afhængig API.
En tredjeparts-widget officielt ikke understøtter SSR.
Komponentens meningsfulde indhold afhænger fuldstændigt af enheds-lokal state som localStorage.
Realtidsdata ændrer sig så hurtigt, at matchning af et server-snapshot har lidt værdi.
I disse tilfælde kan en målrettet klient-afhængig grænse være renere. Nøgleordet er målrettet. Deaktivering af SSR for en hel side for at imødekomme ét diagram eller editor kan ofre nyttigt server-renderet indhold, indlæsningsadfærd og andre fordele unødigt.
Almindelige løsninger, der ser vellykkede ud, men ikke er det
Genvej
Hvorfor den er ufuldstændig
Bedre kriterium
Tilføj 'use client' overalt
Client Components kan stadig forudrenderes i Next.js
Flyt browser-afhængig logik efter hydrering eller isoler den bevidst
Pak render-logik ind i typeof window !== 'undefined'
Grenen selv kan skabe forskellig første-rendering markup
Hold den første rendering identisk
Brug suppressHydrationWarning bredt
Det skjuler en advarsel frem for at afstemme applikationstilstand
Brug kun for en forventet, lokal, uundgåelig uoverensstemmelse
Deaktiver SSR for hele siden
Det kan fjerne symptomet ved at fjerne hydrering for for meget UI
Brug den mindste praktiske klient-afhængige grænse
Test kun klient-side navigation
En uoverensstemmelse kan kun opstå ved en direkte forespørgsel eller hård genindlæsning
Test friske server-renderede sideindlæsninger
Grænser for disse løsninger
En hydreringsfejl fortæller dig, at server- og klientrendering divergerede; den beviser ikke hvorfor. Det samme symptom kan komme fra applikationslogik, browser-mutation, et bibliotek, et CDN, misdannet HTML eller ændrende data. Der er ikke én enkelt kodeudklip, der sikkert løser alle disse tilfælde.
Derudover garanterer fjernelse af hydreringsadvarsler ikke korrekthed andre steder. En klient-afhængig komponent kan stadig have datakapløb. En deterministisk første rendering kan stadig vise forældede data efter hydrering. En gyldig DOM kan stadig indeholde tilgængelighedsproblemer. Behandl hydrering som én kvalitetsport, ikke den eneste.
Reacts 19.3-version nye browser-API betyder heller ikke, at alle frameworks straks skal erstatte deres etablerede browser-afhængige mønster. Framework-integration og installerede versioner betyder noget. Hvis dit projekt er på en ældre React- eller Next.js-udgivelse, så følg dokumentationen for den udgivelse frem for blindt at kopiere en nyere API.
En pålidelig beslutningsrækkefølge
Lokalisér den mindste komponent, der matcher forkert.
Tjek for ændrende værdier såsom datoer, tilfældige tal, lokalitetsformatering og data hentet to gange.
Fjern browser-afhængige API'er fra den første server-kompatible rendering.
Sørg for, at serveren og den første klient-rendering bruger det samme datasnapshot.
Valider HTML-strukturen.
Udeluk udvidelser, CSS-in-JS SSR-konfiguration og CDN/Edge-omskrivning.
Brug en Effect, målrettet klient-afhængig rendering eller React 19.3 use(browser()) kun, når indholdet genuint afhænger af browseren.
Reserver suppressHydrationWarning for små, tilsigtede uoverensstemmelser.
Verificer med en frisk genindlæsning og en produktionsbuild.
Den holdbare løsning er ikke "få React til at stoppe med at klage". Det er at gøre den oprindelige renderingskontrakt eksplicit: Serveren og browseren skal være enige om den første UI, eller den browser-afhængige sektion skal være bevidst isoleret, så React ikke bedes om at hydrere markup, der aldrig kunne matche.