Skip to content

Latest commit

 

History

History
137 lines (103 loc) · 3.94 KB

File metadata and controls

137 lines (103 loc) · 3.94 KB

Next.js App Router 개념 정리

기본 개념

App Router란?

Next.js 13부터 도입된 새로운 라우팅 시스템. 기존 pages/ 디렉토리 방식에서 app/ 디렉토리 방식으로 전환. React Server Components(RSC)를 기본으로 사용한다.

핵심 파일 컨벤션

파일명 역할
page.tsx 라우트의 실제 UI
layout.tsx 공통 레이아웃 (리렌더링 없이 유지)
loading.tsx Suspense 기반 로딩 UI
error.tsx 에러 바운더리
not-found.tsx 404 UI
template.tsx layout과 유사하지만 매 이동마다 새 인스턴스 생성
route.ts API 엔드포인트 (pages/api 대체)

Server Component vs Client Component

  • Server Component: 기본값. 서버에서만 실행. useState, useEffect 사용 불가.
  • Client Component: 파일 상단에 "use client" 선언 필요.

잘 알려지지 않은 상세 개념

1. layout.tsx는 리렌더링되지 않는다

같은 layout을 공유하는 페이지 간 이동 시 layout은 언마운트되지 않는다. 즉, layout 안에서 useState로 상태를 유지하면 페이지가 바뀌어도 상태가 살아있다.

// app/dashboard/layout.tsx
export default function DashboardLayout({ children }) {
  const [sidebarOpen, setSidebarOpen] = useState(true); // 페이지 이동해도 유지됨
  return (
    <div>
      <Sidebar open={sidebarOpen} />
      {children}
    </div>
  );
}

반면 template.tsx는 매 이동마다 새 인스턴스가 생성되어 상태가 초기화된다. 애니메이션 트리거가 필요한 경우에 사용한다.


2. Server Component에서 async/await 직접 사용

Server Component는 async 함수로 선언할 수 있다. fetch, DB 쿼리를 컴포넌트 안에서 바로 실행 가능하다.

// app/posts/page.tsx
export default async function PostsPage() {
  const posts = await fetch("https://api.example.com/posts").then((r) =>
    r.json(),
  );
  return (
    <ul>
      {posts.map((p) => (
        <li key={p.id}>{p.title}</li>
      ))}
    </ul>
  );
}

Next.js는 fetch를 자동으로 캐싱한다. 같은 URL을 여러 컴포넌트에서 호출해도 실제 요청은 한 번만 발생한다(Request Memoization).


3. fetch 캐싱 옵션 3가지

// 기본값: 빌드 시 캐시 (SSG와 동일)
fetch(url);
fetch(url, { cache: "force-cache" });

// 캐시 안 함: 매 요청마다 새로 가져옴 (SSR과 동일)
fetch(url, { cache: "no-store" });

// 일정 시간마다 재검증 (ISR과 동일)
fetch(url, { next: { revalidate: 60 } }); // 60초

페이지 단위로도 설정 가능하다:

export const revalidate = 60; // 이 페이지 전체에 적용
export const dynamic = "force-dynamic"; // 항상 SSR

4. Parallel Routes (병렬 라우트)

@폴더명 컨벤션으로 하나의 layout에서 여러 페이지를 동시에 렌더링할 수 있다.

app/
├── layout.tsx
├── @modal/
│   └── page.tsx   ← modal slot
└── @main/
    └── page.tsx   ← main slot
// app/layout.tsx
export default function Layout({ children, modal, main }) {
  return (
    <div>
      {main}
      {modal} {/* 동시에 렌더링 */}
    </div>
  );
}

대시보드에서 동시에 여러 독립적인 섹션을 렌더링하거나, 모달을 URL 기반으로 관리할 때 사용한다.


5. Intercepting Routes (라우트 인터셉트)

(.), (..), (...) 컨벤션으로 다른 라우트를 가로채서 현재 레이아웃 위에 렌더링한다. Instagram 스타일의 피드에서 사진 클릭 시 모달로 보여주는 패턴에 사용한다.