C.W.K.
Stream
Lesson 05 of 08 · published

Server Component 안 data

~20 min · fetch, async, Promise.all

Level 0Curious
0 XP0/68 lessons0/11 achievements
0/120 XP to next level120 XP to go0% complete

가장 단순한 data 경로

Server Component 가 async function. await data 하고 render. useEffect 없음, loading state machine 없음, client cache 무효화 없음.

두 가지 read 방법

  1. fetch() — HTTP/JSON source 위해. Caching 은 call 별로 (data fetching track 에서 다룰게).
  2. 직접 DB / SDK call — Prisma, Drizzle, Postgres client, internal service.

Default 가 parallel; 일부러 waterfall

독립 fetch 는 Promise.all 안에. Framework 가 sequential await 들을 마법처럼 parallelize 안 해 — JavaScript 의 현실이지 framework 의 현실 아냐. Sequential 도 두 번째 fetch 가 진짜로 첫 번째에 의존하면 ok.

Fetch 위치

Data 쓰는 component 에서 fetch. Page 에서 layer 셋 거쳐서 prop drill 하지 마; leaf component 가 자기 필요한 거 fetch. Framework 가 single render pass 동안 동일 fetch() dedupe 해 — 같은 URL 묻는 두 sibling 이 한 network request 만 trigger.

Code

Server Component 안 직접 fetch·tsx
export default async function Posts() {
  const res = await fetch('https://api.example.com/posts', {
    next: { revalidate: 60 }, // ISR: 60s
  });
  const posts = await res.json();
  return <PostList posts={posts} />;
}
직접 DB read·tsx
import { db } from '@/lib/db';

export default async function Users() {
  const users = await db.user.findMany({
    include: { posts: true },
    orderBy: { createdAt: 'desc' },
  });
  return <UserTable users={users} />;
}
Parallel fetch·tsx
export default async function Dashboard() {
  const [user, stats, alerts] = await Promise.all([
    getUser(),
    getStats(),
    getAlerts(),
  ]);
  return (
    <>
      <UserHeader user={user} />
      <StatsGrid stats={stats} />
      <AlertBanner alerts={alerts} />
    </>
  );
}
Page 가 아니라 leaf 에서 fetch·tsx
// app/page.tsx
export default function Page() {
  return (
    <>
      <Header />
      <Sidebar />
      <Feed />
    </>
  );
}

// 각 leaf 가 자기 data fetch — Next 가 동일 URL dedupe.
async function Header()  { const user = await getMe();         return <Nav user={user} />; }
async function Sidebar() { const cats = await getCategories(); return <Cats list={cats} />; }
async function Feed()    { const posts = await getFeed();      return <Posts items={posts} />; }

External links

Exercise

data 를 prop 으로 layer 셋 거쳐 drill 하는 page refactor. Fetch 를 진짜 쓰는 leaf 로 옮겨. DevTools 에서 render 여전히 작동, network panel 도 여전히 한 request 인지 확인.

Progress

Progress is local-only — sign in to sync across devices.
이 페이지에서 버그를 발견하셨거나 피드백이 있으세요?문제 신고

댓글 0

🔔 답글 알림 (로그인 필요)
로그인댓글을 남기려면 로그인해 주세요.

아직 댓글이 없어요. 첫 댓글을 남겨보세요.