Domov
» Základné znalosti
»
Ako opraviť chybu Hydration Failed Because the Initial UI Does Not Match
Ako opraviť chybu Hydration Failed Because the Initial UI Does Not Match
Výsledok, ktorý chcete dosiahnuť, je jednoduchý na opis: HTML vygenerované na serveri sa musí zhodovať s tým, čo React vygeneruje pri prvom vykreslení v prehliadači. Keď je to pravda, React môže pripojiť obsluhy udalostí a spraviť stránku interaktívnou bez toho, aby vyvolal chybu nesúladu pri hydratacii, nahradil podstrom alebo zobrazil neočakávaný vizuálny skok.
Hydratacia je proces, pri ktorom React preberie HTML, ktoré bolo už vykreslené na serveri, a v prehliadači k nemu pripojí správanie Reactu. Súčasné dokumenty k hydrateRoot uvádzajú, že obsah vykreslený na klientovi sa očakáva ako identický s obsahom vykresleným na serveri a že nesúlady by sa mali považovať za chyby.
Presné znenie chybového hlásenia sa v priebehu vydaní Reactu a frameworkov menilo. Môžete vidieť staršiu správu, ako je "Hydration failed because the initial UI does not match what was rendered on the server", alebo novšiu správu vysvetľujúcu, že strom vykreslený na serveri nezodpovedal klientovi. Princíp ladenia je rovnaký.
Kontext verzie je dôležitý. K 11. septembru 2026 oficiálna stránka Reactu uvádza React 19.3 ako najnovšiu verziu Reactu, zatiaľ čo aktuálna dokumentácia Next.js identifikuje Next.js 16.3.4 ako najnovšie vydanie Next.js. Ak čítate tento článok neskôr, skontrolujte stránku verzií Reactu a aktuálnu dokumentáciu Next.js, pretože dostupné API a chybové hlásenia sa môžu zmeniť.
Ilustrácia generovaná AI: Začnite lokalizovaním prvej komponenty uvedenej v chybe hydratacie a potvrdením, že problém nastáva pri novom načítaní stránky. Toto nie je skutočná snímka obrazovky prehliadača, Reactu alebo Next.js; ako zdroj pravdy použite overené odkazy na kód a dokumentáciu v článku.
Čo sa považuje za úspešnú opravu?
Nesúďte úspech len podľa toho, či zmizne červené prekrytie vo vývojovom prostredí. Dobrá oprava by mala spĺňať niekoľko kontrol:
Upozornenie alebo chyba hydratacie sa už nezobrazuje pri čistom znovunačítaní.
Počiatočné UI vykreslené na serveri a prvé vykreslenie Reactu v prehliadači predstavujú rovnaký obsah a štruktúru.
Ovplyvnená komponenta zostáva po hydratacii interaktívna.
Nedochádza k zjavnému bliknutiu z jednej hodnoty na druhú, pokiaľ táto zmena nie je zámerne navrhnutá.
Problém zostáva vyriešený v produkčnom zostavení, nielen vo vývojovom serveri.
Opravili ste príčinu, namiesto toho, aby ste skryli skutočný nesúlad pomocou možnosti potlačenia upozornenia.
Ak upozornenie zmizne, ale stránka teraz vykresľuje dôležitý obsah až po načítaní JavaScriptu, chyba môže byť preč, no používateľský zážitok sa zhoršil. To môže byť rozumný kompromis pre widget určený iba pre prehliadač, ale nie je to automaticky najlepší výsledok pre primárny obsah stránky.
Krok 1: Reprodukovanie nesúladu a nájdenie najmenšej zlyhávajúcej komponenty
Začnite tvrdým znovunačítaním vo vývojovom prostredí a prečítajte si celú chybu vrátane zásobníka komponent. Dokumentovaná chyba hydratacie v Reacte 19 uvádza niekoľko bežných príčin: vetvenia server/klient, ako je typeof window !== 'undefined', meniace sa hodnoty, ako je Date.now() alebo Math.random(), formátovanie dátumov závislé od lokality, externé dáta, ktoré sa zmenili bez snímky, neplatné hniezdenie HTML a rozšírenia prehliadača, ktoré upravujú DOM. Pozri chybu Reactu 418.
Next.js uvádza podobný zoznam vo svojej oficiálnej príručke k chybám hydratacie, pričom pridáva API dostupné iba v prehliadači, ako sú window a localStorage, konfiguráciu CSS-in-JS a HTML upravené vrstvou Edge/CDN.
Ilustrácia generovaná AI: Zúžte chybu na výraz, ktorý môže produkovať inú hodnotu na serveri a v prehliadači, ako je dátum, náhodné číslo, lokalita alebo hodnota odvodená z prehliadača. Toto nie je skutočná snímka obrazovky prehliadača, Reactu alebo Next.js; ako zdroj pravdy použite overené odkazy na kód a dokumentáciu v článku.
Praktickou metódou izolácie je dočasne nahradiť podozrivé dynamické sekcie deterministickým textom. Ak chyba zmizne, obnovte tieto sekcie jednu po druhej. Toto je zvyčajne rýchlejšie ako zmena globálnych nastavení vykresľovania skôr, než viete, ktorá komponenta je zodpovedná.
Signál kvality
Ste pripravení pokračovať, keď dokážete pomenovať zlyhávajúcu komponentu aj hodnotu alebo štruktúru, ktorá sa líši. "Stáva sa to niekde v dashboardi" je stále príliš všeobecné. "Časová pečiatka v StatusCard sa generuje nezávisle na serveri a klientovi" je akčné.
Krok 2: Odstránenie nedeterministických hodnôt z počiatočného vykreslenia
Deterministické vykresľovanie znamená, že rovnaké vstupy produkujú rovnaké počiatočné UI. Hodnoty, ktoré sa nezávisle menia medzi serverovým a prehliadačovým vykreslením, sú častými zdrojmi nesúladu.
Zvážte tento problematický vzor:
export default function LastUpdated() {
return <time>{new Date().toLocaleString()}</time>;
}
Server a prehliadač môžu tento kód spustiť v rôznych časoch a v rôznych lokalitách alebo časových pásmach. Lepšie riešenie závisí od toho, čo má stránka komunikovať.
Ak časová pečiatka predstavuje serverové dáta, vypočítajte alebo načítajte ich raz na serveri a prejdite rovnakú serializovanú hodnotu na klienta:
Ak hodnota skutočne závisí od prehliadača používateľa, najprv vykreslite stabilný zástupný symbol a aktualizujte ho po hydratacii.
Ilustrácia generovaná AI: Stabilná počiatočná hodnota sa môže čisto hydratovať a potom sa po namontovaní komponenty môže aplikovať obsah špecifický pre prehliadač. Toto nie je skutočná snímka obrazovky prehliadača, Reactu alebo Next.js; ako zdroj pravdy použite overené odkazy na kód a dokumentáciu v článku.
Toto funguje, pretože server a prvé klientske vykreslenie produkujú rovnaký zástupný symbol. Dokumentácia Reactu k useEffect opisuje tento dvojstupňový vzor pre zriedkavé prípady, keď sa klientsky obsah musí líšiť od serverového obsahu.
Kedy zmeniť prístup
Ak je hodnota dostupná iba v prehliadači celým účelom komponenty – napríklad editor obnovený z localStorage alebo widget, ktorý sa nedá zmysluplne vykresliť na serveri – vynútenie vzoru zástupného symbolu a efektu v celej komponente môže pridať zbytočnú zložitosť. V takom prípade použite zámerne vytvorenú hranicu iba pre prehliadač namiesto predstierania, že komponenta je vykresliteľná na serveri.
Krok 3: Nečítajte API dostupné iba v prehliadači počas prvého serverovo kompatibilného vykreslenia
Bežným omylom v Next.js je domnienka, že pridanie 'use client' zaručuje, že sa komponenta vykreslí iba v prehliadači. To nie je pravda. Next.js vysvetľuje, že Client Components sú hranicou pre stav, efekty, obsluhy udalostí a API prehliadača, ale Client Components sa stále môžu podieľať na predbežnom vykresľovaní. Pozri aktuálnu dokumentáciu k use client.
Na serveri localStorage neexistuje. Aj vetvenie, ako je typeof window !== 'undefined', môže produkovať odlišné markupy pri prvom vykreslení v prehliadači, čo React aj Next.js dokumentujú ako príčinu nesúladu pri hydratacii.
Pre malé rozdiely presuňte čítanie z prehliadača do Efektu. Pre komponentu, ktorá by mala byť v Next.js skutočne iba pre prehliadač, ju môžete dynamicky načítať so zakázaným SSR:
Ilustrácia generovaná AI: Použite hranicu iba pre klienta pre komponenty, ktoré fundamentálne závisia od API prehliadača, namiesto toho, aby ste nechali server a prehliadač vykresľovať rôzne stromy. Toto nie je skutočná snímka obrazovky prehliadača, Reactu alebo Next.js; ako zdroj pravdy použite overené odkazy na kód a dokumentáciu v článku.
Next.js dokumentuje ssr: false pre Client Components vo svojej príručke lazy loading. Tá istá príručka uvádza, že ssr: false nie je podporované, keď sa pokúšate použiť túto možnosť priamo v Server Component; presuňte dynamický import do Client Component.
React 19.3: prvotriedna možnosť iba pre prehliadač
React 19.3 zaviedol API browser. Komponenta môže zavolať use(browser()) vnútri hranice Suspense, aby túto komponentu vylúčila zo serverového vykresľovania. Server vykreslí fallback Suspense, zatiaľ čo komponenta sa normálne vykreslí v prehliadači. Pozri referenciu API browser v Reacte.
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>
);
}
V aplikácii React Server Components React uvádza, že use(browser()) musí byť volaný z Client Component. Tiež overte, či váš framework a nainštalovaná verzia Reactu exposingujú toto API pred jeho prijatím.
Krok 4: Urobte zo serverových dát a prvých klientských dát rovnakú snímku
Snímka je presný stav dát použitý na vygenerovanie počiatočného HTML. Hydratacia sa stáva krehkou, ak server vykreslí jednu verziu dát a klient okamžite načíta novšiu alebo inak zoradenú verziu pred dokončením hydratacie.
Ilustrácia generovaná AI: Prvé klientske vykreslenie by malo spotrebovať rovnakú počiatočnú snímku dát, ktorá vytvorila serverové HTML; neskoršie aktualizácie môžu nastať po hydratacii. Toto nie je skutočná snímka obrazovky prehliadača, Reactu alebo Next.js; ako zdroj pravdy použite overené odkazy na kód a dokumentáciu v článku.
Napríklad predpokladajme, že server vykreslí cenu 99 USD, ale klient okamžite načíta rovnaký produkt a získa 109 USD pred svojím prvým vykreslením. Problémom nie je to, že sa dáta zmenili; zmena dát je normálna. Problémom je, že dve prostredia použili rôzne počiatočné vstupy.
Silným vzorom je:
Načítať počiatočné dáta na serveri.
Vykresliť HTML z týchto dát.
Prejsť alebo serializovať rovnaké počiatočné dáta do klientskej komponenty.
Po hydratacii umožniť klientovi revalidovať a aktualizovať, ak existujú novšie dáta.
Správna implementácia závisí od modelu načítavania dát vášho frameworku, ale kritérium kvality zostáva rovnaké: serverové HTML a prvý klientsky strom by mali byť založené na rovnakom logickom stave.
Kedy zmeniť prístup
Ak je obsah inherentne real-time a zastaraná serverová snímka by mohla používateľov uviesť do omylu – napríklad live obchodný widget alebo rýchlo sa meniaca operačná konzola – zvážte vykreslenie stabilného obalu na serveri a načítanie live sekcie na klientovi. To obetuje nejaký serverovo vykreslený obsah pre túto oblasť, ale môže to byť úprimnejšie ako hydratacia proti dátam, ktoré sú zaručené na zmenu.
Krok 5: Opravte neplatné HTML skôr, než obviníte React
Prehliadače majú povolené opravovať zle formátované alebo neplatne hniezdené HTML. Táto oprava môže produkovať štruktúru DOM, ktorá sa líši od štruktúry, ktorú React očakáva, aj keď JSX vyzeral vizuálne pravdepodobne.
Ilustrácia generovaná AI: Skontrolujte sémantické hniezdenie HTML, keď sa strom komponent zdá byť deterministický, ale prehliadač stále konštruuje iný DOM. Toto nie je skutočná snímka obrazovky prehliadača, Reactu alebo Next.js; ako zdroj pravdy použite overené odkazy na kód a dokumentáciu v článku.
Next.js explicitne uvádza príklady, ako je <div> vnútri <p>, zoznam vnútri odseku, hniezdené odkazy a hniezdené tlačidlá ako príčiny problémov s hydrataciou.
Napríklad sa vyhnite:
<p>
Intro text
<div>Details</div>
</p>
Namiesto toho použite platnú štruktúru:
<div>
<p>Intro text</p>
<div>Details</div>
</div>
Ak značka generuje komponentová knižnica, skontrolujte finálny DOM namiesto predpokladu, že obalové prvky sú platné. Pomôcť môže pravidlo lintu alebo validátor HTML, ale skutočný DOM prehliadača je to, čo React hydratuje.
Krok 6: Vylúčte kód mimo komponenty
Ak je vaša logika vykresľovania deterministická a vaše HTML je platné, skontrolujte, či niečo upravuje serverové HTML skôr, než ho React hydratuje.
Oficiálna dokumentácia Next.js uvádza niekoľko možností:
Rozšírenie prehliadača zmení stránku pred načítaním Reactu.
Knižnica CSS-in-JS je nesprávne nakonfigurovaná pre serverové vykresľovanie.
Funkcia Edge alebo CDN prepisuje alebo minifikuje odpoveď HTML.
Na iOS môže automatická detekcia telefónnych čísel, e-mailových adries, dátumov alebo adries v niektorých prípadoch zmeniť text na odkazy.
Používajte kontrolované porovnania. Testujte v súkromnom okne prehliadača so zakázanými rozšíreniami. Ak sa chyba vyskytuje iba za CDN, porovnajte ju s odpoveďou zdroja. Ak začala po prijatí knižnice štýlov, postupujte podľa oficiálnej konfigurácie SSR tejto knižnice namiesto aplikovania všeobecného obchádzania hydratacie.
Signál kvality
Túto triedu problému ste izolovali, keď sa rovnaké zostavenie aplikácie hydratuje správne v jednom kontrolovanom prostredí, ale zlyhá po tom, čo konkrétne rozšírenie prehliadača, proxy, transformácia CDN alebo integrácia zmení HTML.
Krok 7: Použite suppressHydrationWarning iba pre skutočne nevyhnutný lokálny rozdiel
React poskytuje suppressHydrationWarning={true} pre zriedkavé prípady, keď text alebo atribúty jedného prvku nemôžu rozumně zodpovedať, ako sú určité časové pečiatky.
Toto nie je všeobecný mechanizmus opravy. Dokumentácia Reactu k bežným props DOM uvádza, že táto možnosť funguje iba jednu úroveň hlboko a je určená ako núdzový východ. Príručka hydratacie Next.js tiež varuje, že React sa nepokúsi opraviť nesúlad textového obsahu, keď sa táto možnosť použije.
Použite ju iba vtedy, keď platia všetky tieto body:
Rozdiel je očakávaný a lokalizovaný.
Nesúlad neznamená nesprávny stav aplikácie.
Okolitá štruktúra je stabilná.
Vedomo ste akceptovali, že počiatočná hodnota na serveri a hodnota v prehliadači sa líšia.
Ak pridanie propu spôsobí zmiznutie desiatok upozornení, je to dôvod na ďalšie vyšetrovanie, nie znak toho, že je základný problém vyriešený.
Krok 8: Overte opravu vo vývoji a produkcii
Ilustrácia generovaná AI: Po zmene kódu overte čisté znovunačítanie, správnu interaktivitu a produkčné zostavenie namiesto spoliehania sa iba na vývojové prekrytie. Toto nie je skutočná snímka obrazovky prehliadača, Reactu alebo Next.js; ako zdroj pravdy použite overené odkazy na kód a dokumentáciu v článku.
Správanie vo vývoji sa môže líšiť od optimalizovaného produkčného zostavenia. Po tom, čo chyba lokálne zmizne, vykonajte produkčný typ kontroly pre váš framework. Pre typický projekt Next.js to často znamená zostavenie a spustenie aplikácie pomocou vašich bežných príkazov správcu balíčkov, potom vykonanie nových navigácií a znovunačítaní.
Použite tento kontrolný zoznam overenia:
Kontrola
Dobrý znak
Ak zlyhá
Nové znovunačítanie
Žiadna chyba hydratacie v konzole
Znovu skontrolujte najskôr sa líšiacu komponentu
Počiatočný vizuálny stav
Žiadne nežiaduce bliknutie alebo nahradenie
Urobte počiatočný stav deterministickým
Interakcie
Tlačidlá, formuláre, menu a stav fungujú normálne
Potvrďte, že sa komponenta stále hydratuje a obsluhy udalostí sa pripájajú
Produkčné zostavenie
Rovnaký správny výsledok ako vo vývoji
Vyšetrite produkčné dáta, CDN, CSS alebo správanie optimalizácie
Rozšírenia zakázané
Výsledok je nezmenený
Identifikujte správanie rozšírenia upravujúceho DOM
Ak priamo vlastníte vstupný bod React SSR namiesto použitia frameworku, hydrateRoot tiež podporuje spätné volania chýb, ako je onRecoverableError, čo môže pomôcť pri produkčnom logovaní. Používatelia frameworkov by všeobecne nemali nahrádzať vstupný bod hydratacie frameworku len preto, aby pridali vlastné spracovanie.
Kedy vyskúšať inú stratégiu vykresľovania
Ilustrácia generovaná AI: Zmeňte stratégiu, keď komponenta fundamentálne nemôže produkovať zmysluplné serverové HTML, ale udržujte hranicu iba pre klienta čo najmenšiu. Toto nie je skutočná snímka obrazovky prehliadača, Reactu alebo Next.js; ako zdroj pravdy použite overené odkazy na kód a dokumentáciu v článku.
Niekedy najlepšou opravou nie je nútiť komponentu do SSR. Zvážte inú stratégiu vykresľovania, keď:
Komponenta je postavená okolo window, canvas, WebGL, meraní prehliadača alebo iného API dostupného iba v prehliadači.
Widget tretej strany oficiálne nepodporuje SSR.
Zmysluplný obsah komponenty závisí úplne od stavu lokálneho pre zariadenie, ako je localStorage.
Real-time dáta sa menia tak rýchlo, že zodpovedanie snímke servera má malú hodnotu.
V týchto prípadoch môže byť cielená hranica iba pre klienta čistejšia. Kľúčovým slovom je cielená. Zakázanie SSR pre celú stránku, aby sa vyhovelo jednému grafu alebo editoru, môže zbytočne obetovať užitočný serverovo vykreslený obsah, správanie pri načítavaní a ďalšie výhody.
Bežné opravy, ktoré vyzerajú ako úspešné, ale nie sú
Zkratka
Prečo je neúplná
Lepšie kritérium
Pridať 'use client' všade
Client Components sa stále môžu predbežne vykresliť v Next.js
Presuňte logiku iba pre prehliadač po hydratacii alebo ju zámerně izolujte
Zabaľte logiku vykresľovania do typeof window !== 'undefined'
Vetvenie samo môže vytvoriť odlišný markup prvého vykreslenia
Udržujte prvé vykreslenie identické
Použiť suppressHydrationWarning široko
Skryje upozornenie namiesto zosúladenia stavu aplikácie
Použiť iba pre očakávaný, lokálny, nevyhnutný nesúlad
Zakázať SSR pre celú stránku
Môže odstrániť symptóm odstránením hydratacie pre príliš veľa UI
Použiť najmenšiu praktickú hranicu iba pre klienta
Testovať iba klientsku navigáciu
Nesúlad sa môže objaviť iba pri priamej požiadavke alebo tvrdom znovunačítaní
Testujte nové načítania stránok vykreslených na serveri
Obmedzenia týchto opráv
Chyba hydratacie vám hovorí, že serverové a klientske vykresľovanie sa rozchádzali; nedokazuje prečo. Rovnaký príznak môže pochádzať z logiky aplikácie, mutácie prehliadača, knižnice, CDN, zle formátovaného HTML alebo meniacich sa dát. Neexistuje jeden úryvok kódu, ktorý by bezpečne opravil všetky tieto prípady.
Tiež, odstránenie upozornení na hydrataciu nezaručuje správnosť inde. Komponenta iba pre klienta môže mať stále dátové preteky. Deterministické prvé vykreslenie môže stále zobrazovať zastarané dáta po hydratacii. Platný DOM môže stále obsahovať problémy s prístupnosťou. Považujte hydrataciu za jednu kvalitatívnu bránu, nie za jedinú.
Nové API browser v Reacte 19.3 tiež neznamená, že každý framework by mal okamžite nahradiť svoju ustálenú stratégiu iba pre prehliadač. Integrácia frameworku a nainštalované verzie sú dôležité. Ak je váš projekt na staršej verzii Reactu alebo Next.js, postupujte podľa dokumentácie pre toto vydanie namiesto slepého kopírovania novšieho API.
Spoľahlivý poradie rozhodovania
Lokalizujte najmenšiu komponentu, ktorá sa nezhoduje.
Skontrolujte meniace sa hodnoty, ako sú dátumy, náhodné čísla, formátovanie lokality a dáta načítané dvakrát.
Odstráňte API dostupné iba v prehliadači z prvého serverovo kompatibilného vykreslenia.
Zaistite, aby server a prvé klientske vykreslenie používali rovnakú snímku dát.
Validujte štruktúru HTML.
Vylúčte rozšírenia, konfiguráciu SSR CSS-in-JS a prepisovanie CDN/Edge.
Použite Efekt, cielené klientske vykresľovanie alebo React 19.3 use(browser()) iba vtedy, keď obsah skutočne závisí od prehliadača.
Vyhraďte suppressHydrationWarning pre malé, zámerné nesúlady.
Overte novým znovunačítaním a produkčným zostavením.
Trvalá oprava nie je "prinútiť React prestať sťažovať sa". Je to explicitné stanovenie zmluvy o počiatočnom vykresľovaní: server a prehliadač by sa mali zhodnúť na prvom UI, alebo by mala byť sekcia iba pre prehliadač zámerně izolovaná, aby sa React nežiadalo hydratovať markup, ktorý by nikdy nemohol zodpovedať.