
📅 2025-12-02
➡️ Next.js 서버/클라이언트 컴포넌트, 페이지 전환 방식과 렌더링 전략(CSR/SSR/SSG/ISR)에 대해 새롭게 알게 된 것 또는 헷갈리는 부분 정리 + 🤔❓
<a> 태그 대신 <Link> 컴포넌트 사용클라이언트 사이드 라우팅 지원
prefetching 지원
<Link>가 뷰포트에 보이는 순간 다음 페이지의 코드/데이터 미리 다운로드<a> vs <Link>| 요소 | 설명 |
|---|---|
<a> | 전통적 페이지 이동 페이지 전체 새로고침 발생 느림 |
<Link> | SPA처럼 동작하여 빠름 클릭 즉시 페이지 이동 (prefetch) SEO에 유리 (내부적으로 a 태그 렌더링) |
"use client" 선언 필요"use client";
import { useRouter } from "next/navigation";
export default function Test () {
const router = useRouter();
const handleButtonClick = () => {
...
// 로직 실행 후 이동
router.push("/new_location");
}
return <button onClick={handleButtonClick}>클릭!</button>
}
| 메서드 | 설명 | 사용 예 |
|---|---|---|
router.push("/page") | 새 URL을 히스토리 스택에 추가 | 일반 페이지 이동 |
router.replace("/page") | 현재 페이지를 새 페이지로 덮어씀 | 로그인 후 뒤로가기 방지 |
router.back() | 브라우저 뒤로 가기와 동일 | 이전 화면으로 이동 |
router.reload() | 새로고침 | 최신 데이터 재요청 |
🔗 https://nextjs.org/docs/app/getting-started/server-and-client-components
| 구분 | 서버 컴포넌트 (기본) | 클라이언트 컴포넌트 |
|---|---|---|
| 실행 위치 | 서버(Node.js 환경) | 브라우저 |
| 선언 방식 | 기본 | "use client" 필요 |
| 브라우저 API | ❌ 사용 불가 | ⭕ 사용 가능 |
| React Hooks (useState, useEffect 등) | ❌ | ⭕ |
| Node API (fs, os 등) | ⭕ | ❌ |
| 상호작용(이벤트) | ❌ | ⭕ |
| 데이터 패칭, SEO, 정적 UI | ⭕ | ⭕ (하지만 서버가 더 효율적) |
"use client" 선언이 있는 파일만 클라이언트 컴포넌트alert, confirm, window, document)// src/app/page.tsx
export default function Home() {
alert("hello"); // 에러
return (
<div>
<h1>Test Page </h1>
<p>Test Next</p>
</div>
);
}useState, useEffect, useRef) 사용 불가fs, os, path 등)const page = () => {
const os = require("os");
console.log(os);
return (
<div>
<h1>Test Page </h1>
<p>Test Next</p>
</div>
);
};
export default page;
console.log()가 브라우저 개발자 도구가 아닌 터미널 로그에 찍힘"use client" 선언 필요 (파일 맨 위에 위치)useState, useEffect, onClick, 모달, alert, 입력 폼 등 모든 UI 인터랙션 처리"use client";
export default function Component() {
return <button onClick={() => alert("Hello!")}>Click</button>;
}
서버 컴포넌트 (기본)
클라이언트 컴포넌트 (필요할 때만)
// src/app/page.tsx
export default function Home() {
return (
<div className="p-8">
안녕하세요 구름 프론트엔드 넥스트 강의 입니다.
<section>
<h1>제목</h1>
<p>내용</p>
<ul>
<li>항목1</li>
<li>항목2</li>
<li>항목3</li>
</ul>
</section>
<Button />
</div>
);
}// src/components/Button.tsx
"use client";
const Button = () => {
return (
<button
onClick={() => {
alert("안녕하세요!");
}}
>
클릭
</button>
);
};
export default Button;| 렌더링 전략 | 빌드 시간 | SEO | 페이지 요청 응답 속도 | 최신 정보 |
|---|---|---|---|---|
| CSR | 짧음 | 나쁨 | 보통 | 맞음 |
| SSR | 짧음 | 좋음 | 느림 | 맞음 |
| SSG | 김 | 좋음 | 빠름 | 아님 |
| ISR | 김 | 좋음 | 빠름 | 아닐 수 있음 |
Next.js 15.1부터 params를 포함한 여러 요청 관련 객체가 Promise 형태로 동작하도록 변경됨
Promise로 변경된 항목
cookiesheadersdraftModeparams in layout.js, page.js, route.js, default.js, generateMetadata, and generateViewportsearchParams in page.jsexport default function Page({ params: { id } }: { params: { id: string } }) {
// ...
}
type PageParams = Promise<{ id: string }>;
export default async function Page({ params }: { params: PageParams }) {
const { id } = await params;
}
params가 Promise 객체로 전달 → await 필요🔗 https://nextjs.org/blog/next-15#async-request-apis-breaking-change