Lesson 23 of 80
Server-rendered HTML arrives inert — hydration is React 'waking it up': attaching event listeners and its internal tree to markup that's already sitting in the DOM, without re-creating it.
12 min read
Every option explains itself — why the right one is right, and why each wrong one is wrong. Miss one and it comes back later on a spaced-repetition schedule.
Question 1 of 2
A component renders `new Date().toLocaleTimeString()` directly during render, in a server-rendered app. What's the likely problem?
Hints without spoilers, and a plain explanation of why a wrong answer was wrong — answered only from this lesson. Free account, no card.
Sign up freeWhat interviewers actually ask about this, and what a strong answer has to cover.
A strong answer covers
Likely follow-ups
When a page is server-rendered, the browser receives real, already-visible HTML — text and images show up immediately, before any JavaScript has run. But that HTML is just static markup: clicking a button does nothing yet, because no event listeners are attached and React doesn't know this DOM exists.
Hydration is React attaching itself to that existing markup: it walks the server-rendered DOM, builds its internal component tree to match it, and wires up event listeners — all without discarding and recreating the DOM nodes, as long as the client's render output matches what the server sent.
// server: renderToString(<App />) -> static HTML sent to the browser
// client:
hydrateRoot(document.getElementById("root"), <App />);
// walks the existing DOM, attaches React instead of rebuilding it
The server sends real, visible HTML — content appears immediately, before any JavaScript has run.
If what the client renders doesn't match the server-rendered HTML — say, code that reads window or Date.now() during render and gets a different value client-side — React logs a hydration mismatch warning and, to recover, throws away the mismatched DOM and re-renders it client-side. This is exactly the "controlled/uncontrolled" DOM-ownership problem from the inputs lesson, at the scale of the whole page.
Date.now(), Math.random(), or anything reading window/localStorage directly during render — the server doesn't have window, and even when it does have a clock, it isn't guaranteed to agree with the client's."What causes a hydration mismatch, and why is it a problem beyond just a console warning?" tests whether you understand hydration as a real reconciliation-adjacent process with a real performance cost when it fails, not just an SSR checkbox.