Data Fetching

Server Components

Understand React Server Components — fetch data directly in components without useEffect.

Server Components vs Client Components

Server Components (default in App Router):

  • Render on the server
  • Can use async/await directly
  • Can access databases and secrets securely
  • Cannot use hooks (useState, useEffect) or browser APIs

Client Components (marked with "use client"):

  • Render in the browser
  • Can use hooks and browser APIs
  • Can handle user interactions
  • Cannot directly access databases

When to Use Each

Use Server Components for:

  • Fetching data
  • Accessing backend resources
  • Keeping sensitive data server-side

Use Client Components for:

  • Interactive UI (buttons, forms)
  • Browser APIs (localStorage, geolocation)
  • Real-time updates

Example

jsx
// Server Component (default - no directive needed)
// app/users/page.tsx

async function getUsers() {
  // Direct database access or fetch - runs on server only
  const res = await fetch('https://api.example.com/users', {
    cache: 'no-store', // Always fresh data
    // or: next: { revalidate: 60 } // Revalidate every 60s
  });
  return res.json();
}

export default async function UsersPage() {
  const users = await getUsers(); // Directly await in component!

  return (
    <div>
      <h1>Users</h1>
      {users.map(user => (
        <div key={user.id}>{user.name}</div>
      ))}
    </div>
  );
}

// Client Component - needs "use client"
// components/LikeButton.tsx
"use client";

import { useState } from 'react';

export function LikeButton({ postId }: { postId: number }) {
  const [liked, setLiked] = useState(false);

  return (
    <button onClick={() => setLiked(!liked)}>
      {liked ? 'Liked!' : 'Like'}
    </button>
  );
}
Try it yourself — JSX