클라이언트 부분 작게 유지하기
Coddy React 여정의 Next.js 핵심 (Next.js Essentials) 섹션에 포함된 레슨 — 47개 중 20번째.
페이지에 상호작용 가능한 버튼 하나가 필요할 때 다음과 같은 솔깃한 지름길이 있습니다. 페이지 최상단에 'use client'를 붙이고 넘어가는 것이죠. 이 방법은 동작합니다. 하지만 Next.js가 방금 제공한 모든 것을 포기하는 가장 흔한 방법이기도 합니다.
규칙 2를 기억하세요: 디렉티브는 파일 전체에 적용됩니다. page를 표시하면 헤딩, 설명, 요리 목록 및 이들이 렌더링하는 모든 component가 전부 client 코드가 되어 브라우저에서 다운로드되고 다시 실행됩니다. 하나의 button이 전체 page를 경계 너머로 끌어당긴 것입니다.
이것을 해결하는 습관은 작고 기계적입니다:
'use client'를 리프(leaves) 컴포넌트로 내리세요.
상호작용이 필요한 부분을 별도의 작은 파일로 추출하고, 해당 파일만 표시하여, 페이지는 서버에 머물도록 하세요:
// app/page.jsx - 여전히 서버 컴포넌트
import LikeButton from '../components/LikeButton';
export default function Home() {
return (
<main>
<h1>Coddy Eats</h1>
<LikeButton />
</main>
);
}두 가지 주의할 점이 있습니다. 첫째, 서버 component는 클라이언트 component를 렌더링할 수 있습니다. 이러한 방향은 완전히 정상적입니다. 둘째, page의 구조는 변경되지 않았으며, 오직 하나의 작은 조각만 이동했습니다.
동일한 습관으로 유도하는 두 번째 오류가 있습니다. server component 안의 button에 onClick을 직접 지정하면 런타임에서 다음과 같이 차단합니다: Event handlers cannot be passed to Client Component props. 핸들러는 function입니다. client 파일 내에 존재하지 않는 한 브라우저로 전송될 수 없습니다.
챌린지
쉬움이 페이지는 서버 컴포넌트 내부의 버튼에 onClick을 추가했기 때문에 앱이 전혀 렌더링되지 않습니다.
페이지를 클라이언트 컴포넌트로 표시하지 **않고** 해결하세요:
components/LikeButton.jsx에 좋아요 수를 상태(state)에 저장하고id="like"버튼을 렌더링하는 클라이언트 컴포넌트(1번째 줄에'use client')를 작성하세요. 버튼의 텍스트는Likes:뒤에 카운트가 이어지는 형태여야 합니다.app/page.jsx에서 오류가 발생하는 버튼을 삭제하고 대신<LikeButton />를 렌더링하세요.'../components/LikeButton'에서 불러와야 합니다.- 제목과 태그라인(tagline)은 정확히 그대로 두세요. 페이지는 서버 컴포넌트로 유지되어야 합니다.
직접 해보기
import './globals.css';
export const metadata = {
title: 'My App',
};
export default function RootLayout({ children }) {
return (
<html lang="en">
<body>
{children}
</body>
</html>
);
}이 레슨에는 짧은 퀴즈가 포함되어 있습니다. 레슨을 시작해 문제를 풀고 진행 상황을 기록하세요.