icon안동민 개발노트

템플릿 컴포넌트 활용


 Next.js의 템플릿 컴포넌트는 레이아웃과 유사하지만 독특한 특성을 가진 강력한 기능입니다.

 이 절에서는 템플릿 컴포넌트의 개념, 레이아웃과의 차이점, 그리고 적절한 사용 사례에 대해 알아보겠습니다.

템플릿 컴포넌트의 개념

 템플릿 컴포넌트는 template.js 파일로 정의되며, 라우트 세그먼트의 UI를 감싸는 역할을 합니다.

 레이아웃과 유사하게 작동하지만, 몇 가지 중요한 차이점이 있습니다.

레이아웃과 템플릿의 차이점

  1. 상태 유지 : 레이아웃은 라우트 간 이동 시 상태를 유지하지만, 템플릿은 매 네비게이션마다 새 인스턴스를 생성합니다.
  2. 리렌더링 : 템플릿은 라우트 변경 시마다 리렌더링되므로, 애니메이션 효과 등을 적용하기에 적합합니다.
  3. 중첩 : 템플릿은 레이아웃 내부에 중첩되며, 페이지나 하위 세그먼트를 감싸게 됩니다.

template.js 파일의 특징과 사용 방법

 템플릿 컴포넌트의 기본 구조는 다음과 같습니다.

export default function Template({ children }) {
  return (
    <div>
      {/* 템플릿 특정 UI 요소 */}
      {children}
    </div>
  )
}

 템플릿 사용 예시

// app/dashboard/template.js
'use client'
 
import { useState, useEffect } from 'react'
import LoadingSpinner from './LoadingSpinner'
 
export default function DashboardTemplate({ children }) {
  const [isLoading, setIsLoading] = useState(true)
 
  useEffect(() => {
    // 데이터 로딩 시뮬레이션
    const timer = setTimeout(() => setIsLoading(false), 1000)
    return () => clearTimeout(timer)
  }, [])
 
  return (
    <div className="dashboard-template">
      {isLoading ? <LoadingSpinner /> : children}
    </div>
  )
}

 이 예시에서 템플릿은 대시보드 페이지에 로딩 상태를 추가합니다.

 매 네비게이션마다 새로운 로딩 상태가 시작됩니다.

레이아웃 대신 템플릿을 사용해야 하는 경우

  1. 페이지 전환 효과 : 라우트 변경 시 특정 애니메이션이나 전환 효과가 필요한 경우
  2. 동적 초기화 : 매 페이지 로드마다 특정 상태나 효과를 재설정해야 하는 경우
  3. 성능 최적화 : 특정 컴포넌트나 로직이 매 라우트 변경 시 재실행되어야 하는 경우

8장 상태 관리 및 폼 처리와의 연결

 템플릿 컴포넌트는 8장에서 다루는 상태 관리 및 폼 처리와 밀접하게 연관됩니다.

 템플릿은 매 라우트 변경 시 새로운 인스턴스를 생성하므로, 폼의 초기 상태를 설정하거나 특정 상태를 리셋하는 데 유용할 수 있습니다.

 또한, 클라이언트 사이드 상태 관리 라이브러리와 함께 사용하여 라우트별로 독립적인 상태를 관리할 수 있습니다.

실습 : 사용자 인증 상태에 따른 템플릿 컴포넌트 구현

 다음 요구사항을 만족하는 템플릿 컴포넌트를 구현해보세요.

  1. 사용자의 인증 상태를 확인합니다.
  2. 인증된 사용자에게는 대시보드 내용을 보여줍니다.
  3. 인증되지 않은 사용자에게는 로그인 폼을 보여줍니다.
  4. 매 라우트 변경 시 인증 상태를 다시 확인합니다.

 구현 예시

// app/dashboard/template.js
'use client'
 
import { useState, useEffect } from 'react'
import { useRouter } from 'next/navigation'
 
export default function DashboardTemplate({ children }) {
  const [isAuthenticated, setIsAuthenticated] = useState(false)
  const router = useRouter()
 
  useEffect(() => {
    // 인증 상태 확인 (실제 구현에서는 API 호출 등을 사용)
    const checkAuth = async () => {
      // 예시: localStorage를 사용한 간단한 인증 체크
      const token = localStorage.getItem('authToken')
      setIsAuthenticated(!!token)
    }
 
    checkAuth()
  }, [])
 
  if (!isAuthenticated) {
    return (
      <div className="login-form">
        <h2>Please log in to access the dashboard</h2>
        {/* 로그인 폼 컴포넌트 */}
        <button onClick={() => {
          // 로그인 로직 (예시)
          localStorage.setItem('authToken', 'dummy-token')
          setIsAuthenticated(true)
        }}>
          Log In
        </button>
      </div>
    )
  }
 
  return (
    <div className="dashboard-template">
      <h1>Welcome to the Dashboard</h1>
      {children}
    </div>
  )
}

 이 실습을 통해 템플릿 컴포넌트를 사용하여 동적인 인증 로직을 구현하고, 라우트 변경 시마다 인증 상태를 확인하는 방법을 경험할 수 있습니다.

 이는 실제 애플리케이션에서 보안과 사용자 경험을 향상시키는 데 유용한 패턴입니다.