Hydration Mismatch

⭐ Interview Importance: MEDIUM
⏱️ Revision Time: 2 min

Hydration Mismatch

A Hydration Mismatch occurs when the HTML generated by the Server (during SSR or SSG) does not exactly match the HTML that React attempts to render on the Client during the hydration phase.

React expects the client-side Virtual DOM to perfectly mirror the server-provided DOM. If they differ, React throws a Hydration Mismatch Error.

Why Mismatches are Dangerous

When React detects a mismatch, it cannot safely attach event listeners. It assumes the server HTML is corrupted or out-of-sync.

As a fallback, React throws away the entire server-rendered HTML tree and aggressively re-renders the component from scratch.

This ruins the performance benefits of SSR, causes jarring visual flickering for the user, and wastes CPU cycles.

Common Causes of Mismatches

  1. Using Browser-Only APIs:
    If you check window.innerWidth to conditionally render a mobile sidebar, this will fail. The server doesn’t have a window, so it renders the desktop version. The client does have a window, so it tries to render the mobile version. Mismatch!

    // ❌ Causes Mismatch
    function Sidebar() {
      const isMobile = typeof window !== 'undefined' && window.innerWidth < 768;
      return isMobile ? <MobileNav /> : <DesktopNav />;
    }
  2. Using Non-Deterministic Data:
    If you use Math.random() or Date.now() directly in your render logic, the server will generate one random number, and the client will generate a completely different one during hydration.

    // ❌ Causes Mismatch
    function UUIDGenerator() {
      return <div>Your ID is: {Math.random()}</div>;
    }
  3. Invalid HTML Nesting:
    Browsers automatically correct malformed HTML. If your React component renders a <p> inside another <p>, the server sends exactly that. But the browser intercepts it and breaks it into sibling <p> tags. When React tries to hydrate, its Virtual DOM (nested) no longer matches the physical DOM (siblings).

How to Fix Mismatches

The standard way to fix browser-dependent mismatches is to use a useEffect hook (which only runs on the client, never on the server) to wait until hydration is complete before rendering dynamic content.

// ✅ The fix for browser APIs
function Sidebar() {
  const [isMounted, setIsMounted] = useState(false);

  // This only runs on the client AFTER hydration!
  useEffect(() => {
    setIsMounted(true);
  }, []);

  // Server renders this, Client hydrates this
  if (!isMounted) return <DesktopNav />; 

  // Client quickly updates to this if necessary
  const isMobile = window.innerWidth < 768;
  return isMobile ? <MobileNav /> : <DesktopNav />;
}

Interview Questions

Q: What is a Hydration Mismatch?
A: It occurs when the initial static HTML rendered by the server does not exactly match the DOM structure that React calculates when it boots up on the client. This mismatch forces React to destroy and re-create the DOM nodes on the client, completely defeating the performance benefits of SSR.