티스토리 뷰

 

현대 웹 개발에서 '중복'은 관리 비용을 높이는 주범입니다. 특히 모든 페이지에서 공통적으로 사용되는 네비게이션 바, 푸터, 사이드바를 매번 복사해서 붙여넣고 있다면 프로젝트의 유지보수성은 급격히 떨어집니다.

Next.js(App Router)는 이러한 문제를 해결하기 위해 LayoutTemplate이라는 강력한 도구를 제공합니다. 비슷해 보이지만 서로 다른 목적을 가진 이 두 개념을 어떻게 전략적으로 활용해야 할지, 실무 관점에서 깊이 있게 파고들어 보겠습니다.


1. Layout vs Template: 지속성과 초기화의 차이

두 기능 모두 "여러 페이지를 감싸는 공통 UI"를 정의할 때 사용됩니다. 하지만 가장 큰 차이점은 **'상태(State)를 유지하는가, 매번 새로 렌더링하는가'**에 있습니다.

핵심 작동 원리 (Deep Dive)

  • Layout (공통 분모의 수호자): 페이지가 바뀌어도 리렌더링되지 않습니다. 즉, 상단 바의 검색 입력창에 텍스트를 입력한 뒤 다른 메뉴로 이동해도 입력 내용이 그대로 유지됩니다. 브라우저의 DOM 요소를 보존하여 성능을 최적화합니다.
  • Template (새로운 시작의 설계자): 페이지를 이동할 때마다 새로운 인스턴스를 생성합니다. useEffect가 다시 실행되고, 애니메이션이 초기화되며, 상태도 리셋됩니다.

💡 쉽게 비유하자면?

Layout은 거실의 '벽지와 바닥'과 같습니다. 방(Page)을 옮겨 다녀도 벽지와 바닥은 그대로 유지되죠.

반면 Template은 방에 들어갈 때마다 켜지는 '센서등'과 같습니다. 사람이 들어올 때마다 새롭게 반응하여 불을 밝히는 역할을 합니다.


2. 실전 Hands-on: 이커머스 대시보드 설계하기

실제 이커머스 관리자 페이지를 만든다고 가정해 봅시다. 왼쪽에는 메뉴 리스트(Layout)가 있고, 대시보드 진입 시마다 화려한 등장 애니메이션(Template)이 필요합니다.

① Layout: 고정된 사이드바 설정 (layout.tsx)

Layout은 데이터 페칭을 최소화하고 UI 구조를 잡는 데 집중합니다.

TypeScript
 
// app/dashboard/layout.tsx
import SideNavigation from '@/components/SideNavigation';

export default function DashboardLayout({
  children,
}: {
  children: React.ReactNode;
}) {
  return (
    <div className="flex min-h-screen">
      {/* 고정 사이드바: 페이지 이동 시에도 리렌더링되지 않음 */}
      <aside className="w-64 bg-gray-900 text-white p-4">
        <SideNavigation />
      </aside>

      {/* 메인 콘텐츠 영역 */}
      <main className="flex-1 bg-gray-50 p-8">
        {children}
      </main>
    </div>
  );
}

② Template: 진입 애니메이션 적용 (template.tsx)

페이지가 바뀔 때마다 "짠!" 하고 나타나는 효과를 주려면 Template이 적합합니다.

TypeScript
 
// app/dashboard/template.tsx
'use client';

import { motion } from 'framer-motion';

export default function DashboardTemplate({
  children,
}: {
  children: React.ReactNode;
}) {
  return (
    <motion.div
      initial={{ opacity: 0, y: 20 }} // 시작 상태 (투명도 0, 아래로 20px)
      animate={{ opacity: 1, y: 0 }}   // 도착 상태 (투명도 1, 원래 위치)
      transition={{ duration: 0.5 }}  // 0.5초 동안 실행
    >
      {children}
    </motion.div>
  );
}

3. 트러블슈팅: 왜 내 상태값이 자꾸 사라질까?

개발하다 보면 **"분명히 입력 값을 남겨두고 싶은데 페이지 이동만 하면 초기화된다"**는 불평이 나옵니다. 이럴 땐 파일명을 확인해 보세요.

  • 문제: 검색 필터나 폼 데이터를 유지해야 하는데 template.tsx에 로직을 짰을 경우.
  • 해결: 해당 로직을 layout.tsx로 옮기거나, 상태 관리를 URL 쿼리 파라미터(Query String)로 이전하여 Layout 레벨에서 제어해야 합니다.
  • 주의 사항: layout.tsx는 클라이언트 컴포넌트('use client')로 선언할 수 있지만, 검색 엔진 최적화(SEO)를 위해 가급적 최상위 레이아웃은 서버 컴포넌트로 유지하고 필요한 부분만 별도 컴포넌트로 분리하는 것이 좋습니다.

4. 전략적 선택 (Trade-offs)

모든 상황에 정답은 없지만, 일반적인 가이드라인은 다음과 같습니다.

구분 Layout (권장) Template (특수 상황)
상태 유지 페이지 이동 간 데이터 보존 필요 시 페이지 진입 시마다 리셋 필요 시
성능 불필요한 리렌더링 방지로 효율적임 매번 새 요소를 생성하므로 상대적 비용 높음
주요 사례 GNB, 푸터, 사이드바, 유저 프로필 섹션 페이지 전환 애니메이션, 로깅(Enter log) 분석

결론: 구조가 견고해야 코드가 편안하다

Next.js의 Layout과 Template은 단순한 껍데기가 아닙니다. 애플리케이션의 **생명 주기(Lifecycle)**를 결정하는 중요한 설계 포인트입니다.

대부분의 공통 UI는 Layout으로 처리하여 성능을 챙기고, 페이지 전환 효과나 매번 갱신되어야 하는 특정 비즈니스 로직에만 제한적으로 Template을 도입해 보시기 바랍니다.

반응형
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2026/04   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30
글 보관함