🚀 LEVEL UP TO SENIOR:Unlock 500+ Advanced Practical Challenges & Exercises.
🎓 COURSERA PARTNER:Earn professional Google, Meta, and IBM certificates to supercharge your resume.
HTML MASTER CLASS /// LEARN TAGS /// BUILD STRUCTURE /// SEMANTIC WEB /// HTML MASTER CLASS /// LEARN TAGS ///

Modern React Rendering: Server Components, Streaming, and Hydration

A practical guide to modern React rendering: Server Components, 'use client', streaming, selective hydration, and Server Actions.

Total XP: 0|💻 react XP: 0

Skill Matrix

UNLOCK NODES BY LEARNING NEW TAGS.

System Hub

Rendering model.

Quick Quiz //

Which component type can access a database directly but never use useState?


🚀 LEVEL UP TO SENIOR:Unlock 500+ Advanced Practical Challenges & Exercises.
🎓 COURSERA PARTNER:Earn professional Google, Meta, and IBM certificates to supercharge your resume.

Production React apps no longer render everything in the browser. This lesson covers the server/client rendering split that powers modern frameworks: Server Components, Client Components, streaming with Suspense, hydration, and Server Actions.

1Beyond Client-Side Rendering

Modern React applications split their component tree across the server and the client. Server Components render once on the server and produce plain HTML with no client JavaScript cost, while Client Components hydrate in the browser to remain interactive. A single page typically mixes both kinds of components in the same tree.

2Server Components

A Server Component runs exclusively on the server, can access backend resources like a database directly, and contributes zero JavaScript to the client bundle since it never re-renders in the browser. It's the default kind of component in frameworks built on the App Router model, and it's ideal for data-heavy, non-interactive UI.

3Client Components and 'use client'

Any component that needs state, effects, event handlers, or browser-only APIs must be marked with the 'use client' directive at the top of its file. Client Components are still rendered to HTML on the server for the first paint, then hydrated in the browser so their interactivity becomes active.

4Streaming with Suspense

Rather than waiting for every piece of data before sending a response, React can stream a page: fast-rendering sections reach the browser immediately, while slower sections wrapped in a Suspense boundary stream in afterward, replacing their fallback once ready. This lets users see meaningful content far sooner than a fully blocking render would allow.

5Hydration and Selective Hydration

Hydration attaches React's event handlers and internal state to already-rendered server HTML, turning static markup into an interactive application. Selective hydration lets React prioritize hydrating the part of the page a user is actively interacting with, rather than requiring the entire page to finish hydrating before anything responds.

6Server Actions: 'use server'

A function marked with 'use server' always executes on the server, even when it's invoked from an interactive Client Component, such as through a form submission. React manages the network call automatically, letting a Client Component call server-side logic directly instead of requiring a hand-written API route and fetch request.

7Step-by-Step Breakdown

Beyond Client-Side Rendering. So far, every component you've built has run entirely in the browser. Modern React apps split rendering across the server and the client: some components render once on the server and ship as plain HTML, others hydrate and stay interactive in the browser. Understanding this split is essential for building fast, production-grade apps.

Server Components. A React Server Component (RSC) runs only on the server, has zero JavaScript bundle cost on the client, and can directly access backend resources like a database or filesystem. It renders once, produces a description of UI, and never re-renders in the browser — there's no client-side interactivity available inside it.

Client Components and 'use client'. Any component that needs interactivity — state, effects, event handlers, browser APIs — must be a Client Component, marked with the 'use client' directive at the top of the file. Client Components still get server-rendered for the first paint, then hydrate in the browser to become interactive.

Which kind of component can directly query a database, but can never use useState?

  • A Server Component
  • A Client Component

Streaming with Suspense. Instead of waiting for every piece of data before sending any HTML, modern React can stream the page: fast parts render and reach the browser immediately, while slower parts are wrapped in <Suspense> and stream in later, filling their fallback placeholder once ready. The user sees content sooner instead of a blank screen.

Hydration and Selective Hydration. Hydration is the process where React attaches event handlers and internal state to server-rendered HTML, turning static markup into an interactive app. Selective hydration means React can hydrate the parts of the page a user is actually interacting with first, even if other Suspense boundaries are still streaming in — interactivity doesn't have to wait for the entire page.

What is 'selective hydration' designed to improve?

  • Letting the parts of the page a user interacts with become interactive first
  • Making the initial HTML file smaller

Server Actions: 'use server'. A Server Action, marked with 'use server', is a function that always runs on the server, even when called from an interactive Client Component — for example, from a form submission. React handles the network round-trip automatically, so a Client Component can call server logic directly without you writing a manual API route and fetch call.

Mastery Achieved. You now understand the modern React rendering model: Server Components for zero-bundle data access, Client Components for interactivity, streaming with Suspense to show content sooner, hydration (and selective hydration) to make it interactive, and Server Actions to call server logic directly. This is the foundation frameworks like Next.js are built on.

Level Up 🚀

Advanced cheat sheets, SEO tricks, and interview prep for this topic.

Browser Support

ChromeSupported

Streaming and hydration are fully supported in all modern browsers.

FirefoxSupported

Fully supported.

SafariSupported

Fully supported.

EdgeSupported

Fully supported.

Accessibility (A11y)

1Suspense Fallbacks Need Accessible Loading Semantics

A loading fallback shown during streaming should use appropriate ARIA (like role='status' or aria-live='polite') so screen reader users are informed that content is on its way, rather than assuming the page is broken.

2Selective Hydration Shouldn't Leave Controls Silently Unresponsive

A control that's visible but not yet hydrated can appear clickable to a screen reader or keyboard user before it actually responds — avoid rendering interactive-looking elements inside slow Suspense boundaries without a clear pending indication.

SEO Implications

  • 1

    Server Components Ship Fully-Formed HTML to Crawlers

    Because Server Components render on the server before any client JavaScript runs, crawlers see complete, indexable markup immediately, without depending on JavaScript execution to reveal content.

  • 2

    Streaming Reduces Time to First Byte for Meaningful Content

    Sending fast-rendering sections immediately while slower ones stream in later improves perceived load speed, which is a factor in Core Web Vitals metrics that influence search ranking.

Best Practices

Default to Server Components, Opt Into Client Only When Needed

Keep components as Server Components unless they specifically need state, effects, or event handlers — this minimizes client bundle size and maximizes the amount of UI that costs nothing on the client.

Wrap Genuinely Slow Data Fetches in Suspense

Isolate slow, non-critical sections (like a recommendations widget) in their own Suspense boundary so they don't block the rest of the page's initial HTML from streaming to the browser.

Frequent Bugs

THE BUG

Calling useState inside a component throws an error about it not being a Client Component.

THE FIX

Add 'use client' at the top of the file. Any component using state, effects, refs, or event handlers must be explicitly marked as a Client Component — this is not automatic.

THE BUG

A Server Component tries to import and render a component that itself uses 'use client', and everything downstream unexpectedly becomes client-rendered.

THE FIX

Client Components can be rendered from Server Components, but the reverse boundary matters: once you cross into a Client Component, its own children are also client-rendered unless explicitly passed in as already-rendered Server Component children via props/children.

Real-World Examples

A Product Page with Server-Rendered Data and a Client Cart Button

A product detail page is a Server Component that fetches pricing and inventory directly from a database, while the 'Add to Cart' button is a small Client Component marked with 'use client' so it can hold local state and call a Server Action on click.

// page.tsx (Server Component)
async function ProductPage({ id }) {
  const product = await db.products.get(id);
  return (
    <div>
      <h1>{product.name}</h1>
      <AddToCartButton productId={product.id} />
    </div>
  );
}

Interview Prep

?Frequently Asked Questions

Pascual Vila

Pascual Vila

Frontend Instructor // Code Syllabus

Common Pitfalls & Errors

The Error //

Passing a function (like a callback) as a prop from a Server Component to a Client Component

// Wrong: passing a plain function from a Server Component function Page() { const onClick = () => console.log('hi'); // not serializable return <ClientButton onClick={onClick} />; } // Correct: define the handler inside the Client Component 'use client'; function ClientButton() { return <button onClick={() => console.log('hi')}>Click</button>; }

The Solution //

Props crossing the server-to-client boundary must be serializable — functions, class instances, and Dates can't cross that boundary directly. Move the handler logic into the Client Component itself, or use a Server Action for server-side logic.

The Error //

Forgetting 'use client' and getting a 'useState only works in Client Components' error

'use client'; import { useState } from 'react'; function Counter() { const [count, setCount] = useState(0); return <button onClick={() => setCount(count + 1)}>{count}</button>; }

The Solution //

Any file using hooks like useState, useEffect, or useRef, or attaching event handlers like onClick, must start with the 'use client' directive as its very first line.

Lesson Glossary

[01]Server Component (RSC)

A component that renders only on the server, can access backend resources directly, and ships no JavaScript to the client.

Code Preview
async function Page() {...}

[02]Client Component

A component marked with 'use client' that hydrates in the browser and can use state, effects, and event handlers.

Code Preview
'use client';

[03]Streaming

Sending HTML to the browser in progressive chunks instead of waiting for the entire page to be ready.

Code Preview
Progressive HTML delivery

[04]Hydration

The process of attaching event handlers and state to already-rendered server HTML to make it interactive.

Code Preview
hydrateRoot()

[05]Selective Hydration

Prioritizing hydration of the page section a user is actively interacting with, over other pending sections.

Code Preview
Interaction-prioritized hydration

[06]Server Action

A function marked with 'use server' that always runs on the server, callable directly from client code.

Code Preview
'use server';

Continue Learning