Blog / React / React

React Server Components Explained - Complete Guide

Mahesh Mahesh Waghmare
3 min read

React Server Components (RSC) represent a fundamental shift in how React applications are built. They enable server-side rendering with zero JavaScript sent to the client for certain components.

Introduction to Server Components

React Server Components allow you to build components that render on the server, reducing client-side JavaScript and improving performance.

Key Benefits:

  • Zero JavaScript for server components
  • Direct database access
  • Better performance
  • Smaller bundle sizes
  • Improved security

When to Use:

  • Data fetching components
  • Static content
  • Components using server-only APIs
  • Large dependencies

How Server Components Work

Server Components render on the server and send serialized results to the client. The client receives the rendered output, not the component code.

Rendering Flow:

  1. Server renders component
  2. Serializes result to JSON
  3. Sends to client
  4. Client hydrates with minimal JavaScript

Example:

// Server Component (app/page.js in Next.js)
async function ServerComponent() {
    const data = await fetch('https://api.example.com/data');
    const json = await data.json();
    
    return (
        <div>
            <h1>{json.title}</h1>
            <p>{json.content}</p>
        </div>
    );
}
Advertisement

Server vs Client Components

Server Components

  • Render on server
  • No JavaScript sent to client
  • Can use async/await
  • Direct database access
  • Cannot use browser APIs
  • Cannot use hooks like useState, useEffect

Client Components

  • Render on client
  • JavaScript sent to browser
  • Can use browser APIs
  • Can use React hooks
  • Interactive components
  • Mark with ‘use client’ directive

Example:

// Server Component
async function ServerList() {
    const items = await getItemsFromDatabase();
    return (
        <ul>
            {items.map(item => <li key={item.id}>{item.name}</li>)}
        </ul>
    );
}

// Client Component
'use client';

function InteractiveButton() {
    const [count, setCount] = useState(0);
    return (
        <button onClick={() => setCount(count + 1)}>
            Clicked {count} times
        </button>
    );
}

Next.js Implementation

App Router (Next.js 13+)

Server Components are default in App Router:

// app/posts/page.js - Server Component by default
async function PostsPage() {
    const posts = await fetch('https://api.example.com/posts').then(r => r.json());
    
    return (
        <div>
            <h1>Posts</h1>
            {posts.map(post => (
                <article key={post.id}>
                    <h2>{post.title}</h2>
                    <p>{post.excerpt}</p>
                </article>
            ))}
        </div>
    );
}

Client Component in App Router

// app/components/Counter.js
'use client';

import { useState } from 'react';

export default function Counter() {
    const [count, setCount] = useState(0);
    
    return (
        <div>
            <p>Count: {count}</p>
            <button onClick={() => setCount(count + 1)}>Increment</button>
        </div>
    );
}

Mixing Server and Client Components

// app/page.js - Server Component
import ClientCounter from './components/Counter';
import { getServerData } from './lib/server';

export default async function Page() {
    const serverData = await getServerData();
    
    return (
        <div>
            <h1>Server Data: {serverData.title}</h1>
            <ClientCounter />
        </div>
    );
}
Advertisement

Best Practices

  • Use Server Components for data fetching
  • Use Client Components for interactivity
  • Keep Client Components small
  • Pass serializable props between components
  • Avoid importing Client Components in Server Components
  • Use async/await in Server Components
  • Handle errors properly
  • Optimize data fetching
  • Use Suspense for loading states
  • Test both server and client rendering

Conclusion

React Server Components enable:

  • Better performance
  • Smaller bundles
  • Direct server access
  • Improved security

Key principles:

  • Default to Server Components
  • Use Client Components only when needed
  • Keep components focused
  • Optimize data fetching
  • Handle errors gracefully

Understanding Server Components is essential for modern React development with Next.js and similar frameworks.

Advertisement
Mahesh Waghmare

Written by Mahesh Waghmare

I bridge the gap between WordPress architecture and modern React frontends. Currently building tools for the AI era.

Follow on Twitter

Read Next