Hem
» Grundläggande kunskap
»
Så här åtgärdar du felet 'Hydration failed because the initial UI does not match'
Så här åtgärdar du felet 'Hydration failed because the initial UI does not match'
Det önskade resultatet är enkelt att beskriva: HTML-koden som genereras på servern måste matcha det som React genererar vid den första renderingen i webbläsaren. När detta stämmer kan React fästa händelsehanterare och göra sidan interaktiv utan att kasta ett hydreringsfel, ersätta en underträd eller visa en oväntad visuell hoppning.
Hydrering är processen där React tar HTML som redan har renderats på servern och fäster React-beteende till den i webbläsaren. Reacts aktuella dokumentation för hydrateRoot anger att klientrenderat innehåll förväntas vara identiskt med serverrenderat innehåll och att avvikelser bör behandlas som buggar.
Den exakta formuleringen av felet har ändrats över olika versioner av React och ramverk. Du kan se ett äldre meddelande som "Hydration failed because the initial UI does not match what was rendered on the server", eller ett nyare meddelande som förklarar att det serverrenderade trädet inte matchade klienten. Felsökningsprincipen är densamma.
Versionskontext är viktig. Per den 11 september 2026 listar den officiella React-sidan React 19.3 som den senaste React-versionen, medan den aktuella Next.js-dokumentationen identifierar Next.js 16.3.4 som den senaste Next.js-utgåvan. Kontrollera Reacts versionsida och den aktuella Next.js-dokumentationen om du läser detta senare, eftersom tillgängliga API:er och felmeddelanden kan ändras.
AI-genererad illustration: Börja med att lokalisera den första komponenten som nämns i hydreringsfelet och bekräfta att problemet uppstår vid en ny sidoladdning. Detta är inte en faktisk skärmdump från webbläsaren, React eller Next.js; använd de verifierade kod- och dokumentationslänkarna i artikeln som källa till sanning.
Vad räknas som en framgångsrik åtgärd?
Döm inte framgång enbart efter om en röd utvecklingsöverläggning försvinner. En bra åtgärd bör uppfylla flera kontroller:
Hydreringsvarningen eller felet visas inte längre vid en ren omstart.
Den initiala serverrenderade UI:n och webbläsarens första React-rendering representerar samma innehåll och struktur.
Den berörda komponenten förblir interaktiv efter hydrering.
Det finns ingen uppenbar blinkning från ett värde till ett annat, om inte den ändringen är avsiktlig och designad.
Problemet förblir åtgärdat i en produktionsbyggnad, inte bara i utvecklingsservern.
Du har korrigerat orsaken snarare än att dölja en verklig avvikelse med ett alternativ för att undertrycka varningar.
Om varningen försvinner men sidan nu bara renderar viktigt innehåll efter att JavaScript har laddats, kan felet vara borta medan användarupplevelsen har blivit sämre. Det kan vara en rimlig avvägning för en widget som endast är för webbläsaren, men det är inte automatiskt det bästa resultatet för primärt sidinnehåll.
Steg 1: Replikera avvikelsen och hitta den minsta felande komponenten
Börja med en hård omstart i utvecklingsläge och läs hela felet, inklusive komponentstacken. React 19:s dokumenterade hydreringsfel listar flera vanliga orsaker: server/klient-grenar som typeof window !== 'undefined', ändrande värden som Date.now() eller Math.random(), lokalberoende datumformatering, extern data som ändrats utan en ögonblicksbild, ogiltig HTML-nästling och webbläsartillägg som modifierar DOM:en. Se React-fel 418.
Next.js ger en liknande lista i sin officiella guide för hydreringsfel, och lägger till webbläsar-API:er som window och localStorage, CSS-in-JS-konfiguration och HTML som modifierats av ett Edge/CDN-lager.
AI-genererad illustration: Begränsa felet till det uttryck som kan producera ett annat värde på servern och i webbläsaren, såsom ett datum, ett slumpmässigt tal, en lokal eller ett webbläsarhärlett värde. Detta är inte en faktisk skärmdump från webbläsaren, React eller Next.js; använd de verifierade kod- och dokumentationslänkarna i artikeln som källa till sanning.
En praktisk isoleringsmetod är att tillfälligt ersätta misstänkta dynamiska avsnitt med deterministisk text. Om felet försvinner, återställ dessa avsnitt en i taget. Detta är oftast snabbare än att ändra globala renderingsinställningar innan du vet vilken komponent som är ansvarig.
Kvalitetssignal
Du är redo att gå vidare när du kan namnge både den felande komponenten och det värde eller den struktur som skiljer sig åt. "Det händer någonstans i instrumentpanelen" är fortfarande för brett. "Tidsstämpeln i StatusCard produceras oberoende på servern och klienten" är åtgärdbart.
Steg 2: Ta bort icke-deterministiska värden från den initiala renderingen
Deterministisk rendering innebär att samma inmatningar producerar samma initiala UI. Värden som ändras oberoende mellan serverrenderingen och webbläsarrenderingen är vanliga källor till avvikelser.
Överväg detta problematiska mönster:
export default function LastUpdated() {
return <time>{new Date().toLocaleString()}</time>;
}
Servern och webbläsaren kan köra denna kod vid olika ögonblick och i olika lokaler eller tidszoner. En bättre lösning beror på vad sidan ska kommunicera.
Om tidsstämpeln representerar serverdata, beräkna eller hämta den en gång på servern och skicka samma serialiserade värde till klienten:
Om värdet genuint beror på användarens webbläsare, rendera en stabil platshållare först och uppdatera den efter hydrering.
AI-genererad illustration: Ett stabilt initialvärde kan hydrera rent, sedan kan webbläsarspecifikt innehåll tillämpas efter att komponenten har monterats. Detta är inte en faktisk skärmdump från webbläsaren, React eller Next.js; använd de verifierade kod- och dokumentationslänkarna i artikeln som källa till sanning.
Detta fungerar eftersom servern och den första klientrenderingen båda producerar samma platshållare. Reacts useEffect-dokumentation beskriver detta tvåstegsmönster för de sällsynta fallen där klientinnehåll måste skilja sig från serverinnehåll.
När du ska ändra tillvägagångssätt
Om det webbläsarbara värdet är hela syftet med komponenten – till exempel en redigerare som återställs från localStorage eller en widget som inte kan rendera meningsfullt på servern – kan det att tvinga fram ett platshållar-och-effekt-mönster genom hela komponenten lägga till onödig komplexitet. I det fallet, använd en avsiktlig webbläsarbar gräns istället för att låtsas att komponenten är serverrenderbar.
Steg 3: Läs inte webbläsarbara API:er under den första serverkompatibla renderingen
En vanlig missuppfattning i Next.js är att tillsatsen av 'use client' garanterar att komponenten endast renderas i webbläsaren. Det gör den inte. Next.js förklarar att Client Components är gränsen för tillstånd, effekter, händelsehanterare och webbläsar-API:er, men Client Components kan fortfarande delta i förrendering. Se den aktuella use client-dokumentationen.
På servern finns inte localStorage. Även en gren som typeof window !== 'undefined' kan producera olika markup vid den första webbläsarrenderingen, vilket både React och Next.js dokumenterar som en orsak till hydreringsavvikelser.
För små skillnader, flytta webbläsarläsningen till en Effect. För en komponent som verkligen ska vara webbläsarbar i Next.js, kan du dynamiskt ladda den med SSR inaktiverat:
AI-genererad illustration: Använd en klientbar gräns för komponenter som fundamentalt beror på webbläsar-API:er, istället för att låta servern och webbläsaren rendera olika träd. Detta är inte en faktisk skärmdump från webbläsaren, React eller Next.js; använd de verifierade kod- och dokumentationslänkarna i artikeln som källa till sanning.
Next.js dokumenterar ssr: false för Client Components i sin guide för lat inläsning. Samma guide anger att ssr: false inte stöds när du försöker använda det alternativet direkt i en Server Component; flytta den dynamiska importen till en Client Component.
React 19.3: ett förstklassigt webbläsarbart alternativ
React 19.3 introducerade browser-API:t. En komponent kan anropa use(browser()) inuti en Suspense-gräns för att utelämna den komponenten från serverrendering. Servern renderar Suspense-fallbacken, medan komponenten renderas normalt i webbläsaren. Se Reacts browser API-referens.
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 säger React att use(browser()) måste anropas från en Client Component. Verifiera också att ditt ramverk och den installerade React-versionen exponerar detta API innan du antar det.
Steg 4: Gör serverdata och den första klientdatan till samma ögonblicksbild
En ögonblicksbild är det exakta data tillståndet som används för att producera den initiala HTML-koden. Hydrering blir skör om servern renderar en dataversion och klienten omedelbart läser en nyare eller annorlunda ordnad version innan hydreringen är klar.
AI-genererad illustration: Den första klientrenderingen bör konsumera samma initiala dataögonblicksbild som producerade serverns HTML; senare uppdateringar kan ske efter hydrering. Detta är inte en faktisk skärmdump från webbläsaren, React eller Next.js; använd de verifierade kod- och dokumentationslänkarna i artikeln som källa till sanning.
Antag till exempel att servern renderar ett pris på $99, men klienten hämtar omedelbart samma produkt och får $109 innan sin första rendering. Problemet är inte att datan ändrades; att data ändras är normalt. Problemet är att de två miljöerna använde olika initiala inmatningar.
Ett starkt mönster är:
Hämta den initiala datan på servern.
Rendera HTML-koden från den datan.
Skicka eller serialisera samma initiala data till klientkomponenten.
Låt klienten omvalidera och uppdatera om nyare data finns efter hydrering.
Den korrekta implementationen beror på ditt ramverks datahämtningmodell, men kvalitetskriteriet förblir detsamma: serverns HTML och det första klientträdet bör baseras på samma logiska tillstånd.
När du ska ändra tillvägagångssätt
Om innehållet är inneboende realtids och en föråldrad serverögonblicksbild skulle vilseleda användare – till exempel en live-handelswidget eller en snabbt föränderlig operationskonsol – överväg att rendera ett stabilt skal på servern och ladda den live-sektionen på klienten. Det ger upp viss serverrenderat innehåll för den regionen, men det kan vara ärligare än att hydrera mot data som garanterat kommer att ändras.
Steg 5: Åtgärda ogiltig HTML innan du skyller på React
Webbläsare tillåts korrigera felaktig eller ogiltigt nästad HTML. Den korrigeringen kan producera en DOM-struktur som skiljer sig från den struktur React förväntar sig, även när JSX såg visuellt plausibel ut.
AI-genererad illustration: Kontrollera semantisk HTML-nästling när komponentträdet verkar deterministiskt men webbläsaren fortfarande konstruerar en annan DOM. Detta är inte en faktisk skärmdump från webbläsaren, React eller Next.js; använd de verifierade kod- och dokumentationslänkarna i artikeln som källa till sanning.
Next.js listar uttryckligen exempel som en <div> inuti en <p>, en lista inuti ett stycke, nästlade ankare och nästlade knappar som orsaker till hydreringsproblem.
Undvik till exempel:
<p>
Intro text
<div>Details</div>
</p>
Använd en giltig struktur istället:
<div>
<p>Intro text</p>
<div>Details</div>
</div>
Om ett komponentbibliotek genererar markeringen, inspektera den slutliga DOM:en istället för att anta att omslutande element är giltiga. En lint-regel eller HTML-validerare kan hjälpa, men webbläsarens faktiska DOM är det React hydrerar.
Steg 6: Uteslut kod utanför komponenten
Om din renderingslogik är deterministisk och din HTML är giltig, kontrollera om något modifierar serverns HTML innan React hydrerar den.
Officiell Next.js-dokumentation namnger flera möjligheter:
Ett webbläsartillägg ändrar sidan innan React laddas.
Ett CSS-in-JS-bibliotek är felaktigt konfigurerat för serverrendering.
En Edge- eller CDN-funktion skriver om eller minimerar HTML-svaret.
På iOS kan automatisk detektering av telefonnummer, e-postadresser, datum eller adresser i vissa fall ändra text till länkar.
Använd kontrollerade jämförelser. Testa i ett privat webbläsarfönster med tillägg inaktiverade. Om felet uppstår endast bakom ett CDN, jämför mot ursprungsresponsen. Om det började efter att du antog ett stilbibliotek, följ det bibliotekets officiella SSR-konfiguration istället för att tillämpa en allmän hydreringslösning.
Kvalitetssignal
Du har isolerat denna klass av problem när samma applikationsbyggnad hydrerar korrekt i en kontrollerad miljö men misslyckas efter att ett specifikt webbläsartillägg, proxy, CDN-transformation eller integration ändrar HTML-koden.
Steg 7: Använd suppressHydrationWarning endast för en verklig oundviklig lokal skillnad
React tillhandahåller suppressHydrationWarning={true} för sällsynta fall där ett enda elements text eller attribut inte rimligen kan matcha, såsom vissa tidsstämplar.
Detta är inte en allmän reparationsmekanism. Reacts dokumentation för vanliga DOM-props säger att alternativet endast fungerar ett nivå djupt och är avsett som en nödutgång. Next.js hydreringsguide varnar också för att React inte kommer att försöka lappa ihop felaktig textinnehåll när detta alternativ används.
Använd det endast när alla följande är sanna:
Skillnaden är förväntad och lokaliserad.
Avvikelsen representerar inte ett felaktigt applikationstillstånd.
Den omgivande strukturen är stabil.
Du har medvetet accepterat att det initiala servervärdet och webbläsarvärdet skiljer sig åt.
Om tillsatsen av prop:en får dussintals varningar att försvinna, är det en anledning att undersöka vidare, inte ett tecken på att det underliggande problemet är löst.
Steg 8: Verifiera åtgärden i utvecklings- och produktionsmiljö
AI-genererad illustration: Efter att ha ändrat koden, verifiera en ren omstart, korrekt interaktivitet och en produktionsbyggnad istället för att bara förlita sig på utvecklingsöverläggningen. Detta är inte en faktisk skärmdump från webbläsaren, React eller Next.js; använd de verifierade kod- och dokumentationslänkarna i artikeln som källa till sanning.
Utvecklingsbeteendet kan skilja sig från en optimerad produktionsbyggnad. Efter att felet är borta lokalt, utför en produktionsliknande kontroll för ditt ramverk. För ett typiskt Next.js-projekt innebär det ofta att bygga och starta applikationen med dina normala pakethanterarkommandon, och sedan göra nya navigeringar och omstart.
Använd denna verifieringschecklista:
Kontroll
Godt tecken
Om det misslyckas
Ny omstart
Inget hydreringsfel i konsolen
Kontrollera den tidigaste avvikande komponenten igen
Initialt visuellt tillstånd
Ingen oavsiktlig blinkning eller ersättning
Gör det initiala tillståndet deterministiskt
Interaktioner
Knappar, formulär, menyer och tillstånd fungerar normalt
Bekräfta att komponenten fortfarande hydrerar och händelsehanterare fästs
Produktionsbyggnad
Samma korrekta resultat som i utveckling
Undersök produktionsendast data, CDN, CSS eller optimeringsbeteende
Tillägg inaktiverade
Resultatet är oförändrat
Identifiera DOM-modifierande tilläggsbeteende
Om du äger React SSR-ingångspunkten direkt istället för att använda ett ramverk, stöder hydrateRoot också felåterkallningar som onRecoverableError, vilket kan hjälpa till med produktionsloggning. Ramverkanvändare bör generellt inte ersätta ramverkets hydreringsingångspunkt bara för att lägga till anpassad hantering.
När du ska prova en annan renderingsstrategi
AI-genererad illustration: Ändra strategi när en komponent fundamentalt inte kan producera meningsfull server-HTML, men håll den klientbara gränsen så liten som praktiskt möjligt. Detta är inte en faktisk skärmdump från webbläsaren, React eller Next.js; använd de verifierade kod- och dokumentationslänkarna i artikeln som källa till sanning.
Ibland är den bästa åtgärden inte att tvinga en komponent till SSR. Överväg en annan renderingsstrategi när:
Komponenten är byggd runt window, canvas, WebGL, webbläsarmätningar eller ett annat webbläsarbart API.
En tredjeparts-widget officiellt inte stöder SSR.
Komponentens meningsfulla innehåll beror helt på enhetslokal tillstånd som localStorage.
Realtidsdata ändras så snabbt att det att matcha en serverögonblicksbild har lite värde.
I dessa fall kan en riktad klientbar gräns vara renare. Nyckelordet är riktad. Att inaktivera SSR för en hel sida för att rymma en enda graf eller redigerare kan onödigt offra användbart serverrenderat innehåll, laddningsbeteende och andra fördelar.
Vanliga åtgärder som ser framgångsrika ut men inte är det
Genväg
Varför den är ofullständig
Bättre kriterium
Lägg till 'use client' överallt
Client Components kan fortfarande förrenderas i Next.js
Flytta webbläsarbar logik efter hydrering eller isolera den avsiktligt
Omslut renderingslogik i typeof window !== 'undefined'
Grenen i sig kan skapa olika initialrenderad markup
Håll den första renderingen identisk
Använd suppressHydrationWarning brett
Det döljer en varning snarare än att försona applikationstillstånd
Använd endast för en förväntad, lokal, oundviklig avvikelse
Inaktivera SSR för hela sidan
Det kan ta bort symtomet genom att ta bort hydrering för för mycket UI
Använd den minsta praktiska klientbara gränsen
Testa endast klientsidig navigering
En avvikelse kan bara dyka upp vid en direkt begäran eller hård omstart
Testa nya serverrenderade sidladdningar
Begränsningar för dessa åtgärder
Ett hydreringsfel säger dig att server- och klientrenderingen divergerade; det bevisar inte varför. Samma symtom kan komma från applikationslogik, webbläsarmutation, ett bibliotek, ett CDN, felaktig HTML eller ändrande data. Det finns ingen enda kodsnutt som säkert åtgärdar alla dessa fall.
Dessutom garanterar borttagning av hydreringsvarningar inte korrekthet på andra ställen. En klientbar komponent kan fortfarande ha dataracer. En deterministisk första rendering kan fortfarande visa föråldrad data efter hydrering. En giltig DOM kan fortfarande innehålla tillgänglighetsproblem. Behandla hydrering som en kvalitetsgrind, inte den enda.
React 19.3:s nya browser-API betyder heller inte att varje ramverk omedelbart bör ersätta sin etablerade webbläsarbara mönster. Ramverksintegration och installerade versioner spelar roll. Om ditt projekt använder en äldre React- eller Next.js-utgåva, följ dokumentationen för den utgåvan istället för att kopiera ett nyare API blindt.
En pålitlig beslutsordning
Lokalisera den minsta komponenten som avviker.
Kontrollera efter ändrande värden som datum, slumpmässiga tal, lokalformatering och data som hämtats två gånger.
Ta bort webbläsarbara API:er från den första serverkompatibla renderingen.
Säkerställ att servern och den första klientrenderingen använder samma dataögonblicksbild.
Validera HTML-strukturen.
Uteslut tillägg, CSS-in-JS SSR-konfiguration och CDN/Edge-omskrivning.
Använd en Effect, riktad klientbar rendering eller React 19.3 use(browser()) endast när innehållet verkligen beror på webbläsaren.
Reservera suppressHydrationWarning för små, avsiktliga avvikelser.
Verifiera med en ny omstart och en produktionsbyggnad.
Den hållbara åtgärden är inte "få React att sluta klaga". Det är att göra det initiala renderingsavtalet explicit: servern och webbläsaren bör vara överens om den första UI:n, eller så bör den webbläsarbara sektionen avsiktligt isoleras så att React inte ombeds hydrera markup som aldrig kunde matcha.