Question presented to candidate: "Your logs are full of hydration warnings. How do you work out what is causing them and what do you do about each kind?"
What a strong answer should cover:
- A mismatch is the client's first render producing something different from the server HTML. React then discards the mismatched subtree and re-renders it on the client.
- Not all mismatches are equal, which is the key insight: a text or structure mismatch is a recoverable error and the client value wins; an attribute mismatch only warns in the console and the server value is kept.
- The causes fall into four groups: non-deterministic output (
Date,Math.random, generated ids), environment differences (locale, timezone,window,localStorage), invalid HTML nesting the browser silently repairs, and third parties — browser extensions injecting markup. - The fix for a genuinely client-only value is a mounted flag: render the neutral version on the server and the first client render, then switch. Checking
typeof windowduring render does not work — it makes the first client render differ, which is the mismatch. - For a store-backed value,
useSyncExternalStoretakes a server snapshot for exactly this. suppressHydrationWarningis for one unavoidable node, such as a timestamp. It silences the warning and keeps the server value — it does not make the two agree.- Extension-caused mismatches are not your bug; recognise them rather than chasing them.
Clarifying questions expected:
- "Is the differing value genuinely client-only, or just accidentally non-deterministic?" — different fixes.
- "Does the warning reproduce in a clean profile with extensions disabled?"
Code / implementation expected: Optional. The mounted-flag pattern is three lines and worth writing out.