React · Frontend system thinking
How does server-side rendering and hydration work in React?
Short answer
The server renders HTML, the browser paints it, and React hydrates it by attaching event handlers and state to the existing DOM. Markup that differs between server and client causes hydration errors.
Server rendering gives the user HTML before JavaScript loads, which improves first contentful paint and crawlability. Hydration is the client-side pass where React walks the existing DOM, matches it to the component tree, and attaches listeners. It is not the same as rendering the whole app again from scratch.
function Clock() {
const [now, setNow] = useState(null);
useEffect(() => {
setNow(new Date());
const id = setInterval(() => setNow(new Date()), 1000);
return () => clearInterval(id);
}, []);
if (!now) {
return <time>Loading time...</time>;
}
return <time>{now.toLocaleTimeString()}</time>;
}Common mismatch causes
- Reading
window,localStorageornavigatorduring render - Rendering
Date.now()orMath.random()on both sides - Branching on a value that differs between server and client
- Invalid HTML nesting that the browser repairs differently
- Using a different locale or time zone on the server
Move browser-only values into an effect or a client-only boundary, use useId for stable IDs across server and client, and render a deterministic initial state. Do not suppress the warning unless the difference is intentional and harmless; suppressHydrationWarning only covers the immediate element and is not a general fix.
Follow-ups you should expect
Interviewers use these to check whether the first answer was understanding or memorisation.
- 1What is the difference between rendering and hydrating?
- 2How do you fix a window is not defined error?
- 3Why does useId help with SSR?
- 4What happens when hydration fails in React 19?
Say it in the interview
SSR sends HTML so the page can paint before JavaScript arrives. Hydration attaches React's behaviour to that existing DOM without throwing it away. A hydration mismatch happens when the server markup does not match the first client render, often because of browser-only data, time, randomness or invalid HTML. I keep the first render deterministic, move browser APIs into effects, use useId for stable IDs, and never treat suppressHydrationWarning as a blanket fix.
Use this as a model, not a script. Saying it in your own words is what makes it survive follow-up pressure.
Related questions
Reading is step one
Now say it out loud.
Understanding an answer and delivering it under pressure are different skills. Rehearse this topic in a live React mock interview and get scored feedback on depth, clarity and confidence.