Next.js › Data Fetching

How do you fetch data inside a client component that needs to run in the browser?

Beginner

Answer

Since client components cannot use async directly in their function body the way server components can, you typically fetch data inside a useEffect hook, storing the result in state with useState, and showing a loading indicator while the request is in progress.
'use client';
import { useEffect, useState } from 'react';

export default function Comments({ postId }) {
  const [comments, setComments] = useState([]);
  useEffect(() => {
    fetch(`/api/posts/${postId}/comments`).then(res => res.json()).then(setComments);
  }, [postId]);
  return <ul>{comments.map(c => <li key={c.id}>{c.text}</li>)}</ul>;
}
Real-world example A comments section fetches new comments in the browser whenever the user scrolls to it, since comments update frequently and benefit from being fetched client side after the main page has already loaded.

Common follow-ups: Should this data instead be fetched on the server and passed down as props?;What are the tradeoffs between client side and server side data fetching?