JS Guide
HomeQuestionsTopicsCompaniesResources
BookmarksSearch

Built for developers preparing for JavaScript, React & TypeScript interviews.

ResourcesQuestionsSupport
HomeQuestionsSearchProgress
HomeQuestionsreact
PrevNext

Learn the concept

React Internals

react
senior
rendering

Explain React's hydration process and common hydration mismatch issues.

hydration
ssr
streaming
suspense
server-components
performance
Quick Answer

Hydration is the process where React attaches event handlers and state to server-rendered HTML, making it interactive without re-rendering the DOM. Mismatches occur when server and client HTML differ, causing React to discard and re-render the affected subtree.

Detailed Explanation

When using Server-Side Rendering (SSR), the server generates HTML and sends it to the browser. The browser displays this HTML immediately (fast First Contentful Paint). Then React hydrates the page — it walks the existing DOM, attaches event handlers, and connects state management without recreating DOM nodes.

How Hydration Works

  1. Server renders components to an HTML string using renderToString() or renderToPipeableStream()
  2. Browser receives and displays the HTML (page is visible but not interactive)
  3. Browser downloads the JavaScript bundle
  4. React calls hydrateRoot() (React 18+) instead of createRoot()
  5. React traverses the DOM tree and the component tree simultaneously
  6. For each component, React verifies the existing DOM matches what it would render
  7. React attaches event handlers and initializes state — the page becomes interactive

Hydration Mismatches

A hydration mismatch occurs when the HTML rendered on the server differs from what React expects on the client. React logs a warning and may discard the mismatched subtree, re-rendering it from scratch (losing the SSR performance benefit).

Common causes:

  1. Browser-only APIs: Using window, document, localStorage, or navigator during render — these don't exist on the server.

  2. Non-deterministic values: Date.now(), Math.random(), or crypto.randomUUID() produce different values on server vs client.

  3. Browser extensions: Extensions that modify the DOM (ad blockers, password managers, translation tools) add elements React doesn't expect.

  4. Invalid HTML nesting: <p><div>...</div></p> — the browser auto-corrects invalid nesting, creating a DOM that differs from what React generated.

  5. Conditional rendering based on client state: Rendering different content based on window.innerWidth or media queries without proper handling.

Solutions

  • useEffect for client-only logic: Code in useEffect runs only on the client, after hydration.
  • Dynamic imports with next/dynamic: Load client-only components with ssr: false.
  • suppressHydrationWarning: Silence warnings for intentional differences (e.g., timestamps). Use sparingly.
  • Two-pass rendering: Render a placeholder on the server, then update on the client after hydration.

Streaming SSR with Suspense

React 18 introduced streaming SSR with renderToPipeableStream(). Instead of waiting for the entire page to render, the server streams HTML as components resolve:

  1. The server sends the HTML shell immediately
  2. Suspense boundaries show fallback content for unresolved components
  3. As each Suspense boundary resolves, the server streams its HTML along with an inline <script> that swaps the fallback
  4. Hydration happens progressively — resolved sections become interactive while others are still loading

Selective Hydration

React 18 also enables selective hydration: React prioritizes hydrating the component the user is interacting with. If a user clicks a button inside a Suspense boundary that hasn't hydrated yet, React hydrates that boundary first, even if other boundaries are ahead in the queue.

React Server Components vs SSR

SSR renders components to HTML on the server, then hydrates them on the client (the component code ships to the browser). React Server Components (RSC) render on the server and never ship their JavaScript to the client — they send a serialized component tree instead. RSC and SSR are complementary: RSC reduces bundle size, SSR provides fast initial paint.

Code Examples

Common Hydration Mismatch and FixTSX
// BAD — causes hydration mismatch
function Greeting() {
  // window.innerWidth doesn't exist on server
  const isMobile = window.innerWidth < 768; // ❌ Crashes on server
  return <p>{isMobile ? 'Mobile' : 'Desktop'} view</p>;
}

// GOOD — two-pass rendering
function Greeting() {
  const [isMobile, setIsMobile] = useState(false);

  useEffect(() => {
    // Runs only on client, after hydration
    setIsMobile(window.innerWidth < 768);

    const handleResize = () => setIsMobile(window.innerWidth < 768);
    window.addEventListener('resize', handleResize);
    return () => window.removeEventListener('resize', handleResize);
  }, []);

  return <p>{isMobile ? 'Mobile' : 'Desktop'} view</p>;
}

// GOOD — suppress warning for timestamps
function Comment({ timestamp }) {
  return (
    <time suppressHydrationWarning>
      {new Date(timestamp).toLocaleString()}
    </time>
  );
}

Real-World Applications

Use Cases

E-commerce Pages

Product pages use streaming SSR to show the product title and image immediately while reviews and recommendations load progressively via Suspense boundaries.

News and Content Sites

Article pages hydrate the main content first for fast readability, while interactive widgets (comments, share buttons) hydrate lazily.

Mini Projects

Hydration Mismatch Debugger

advanced

Build a development tool that detects hydration mismatches in a Next.js app by comparing server-rendered HTML with client-rendered output, highlighting differences.

Industry Examples

Vercel (Next.js)

Next.js App Router uses React's streaming SSR and selective hydration by default, with Suspense boundaries for progressive loading.

Resources

React Docs - hydrateRoot

docs

React Docs - Server APIs

docs

web.dev - Streaming Server Rendering

article

Related Questions

What are the differences between CSR, SSR, and SSG in React applications?

mid
rendering

What are React's concurrent features and how do Suspense and transitions work?

senior
concurrent

How does React's reconciliation algorithm work?

senior
internals
Previous
How does list virtualization (windowing) work in React and when should you use it?
Next
Explain React's diffing algorithm in detail. How does it achieve O(n) complexity?
PrevNext