챕터 21: Link 컴포넌트 완벽 가이드
서론 지금까지 우리는 페이지 간 이동을 위해 일반적인 HTML의 태그를 사용했습니다. 하지만 Next.js는 더 나은 방법을 제공합니다. 바로 Link 컴포넌트입니다. Link 컴포넌트를 사용하면 페이지 전체를 새로고침하지 않고도 빠르게 이동할 수 있어, 사용자 경험이 크게 향상됩니다.
Link 컴포넌트는 단순히 페이지를 이동시키는 것 이상의 기능을 제공합니다. 자동 프리페칭, 스크롤 복원, 동적 라우팅 지원 등 다양한 최적화 기능이 내장되어 있습니다. 이번 챕터에서는 Link 컴포넌트의 모든 기능을 완벽하게 마스터해보겠습니다.
본론 Link vs a 태그의 차이 먼저 일반 a 태그와 Link 컴포넌트의 차이를 이해해봅시다:
jsx 'use client'
import Link from 'next/link'
export default function LinkVsAnchor() { return (
Link vs a 태그 비교
<div className="grid grid-cols-2 gap-8">
{/* a 태그 사용 */}
<div className="bg-white p-6 rounded-lg shadow">
<h2 className="text-xl font-semibold mb-4">일반 a 태그</h2>
<a href="/about" className="text-blue-600 hover:underline">
About 페이지로 (전체 새로고침)
</a>
<ul className="mt-4 text-sm text-gray-600 space-y-1">
<li>❌ 페이지 전체 새로고침</li>
<li>❌ 느린 페이지 전환</li>
<li>❌ 상태 초기화</li>
<li>❌ 프리페칭 없음</li>
</ul>
</div>
{/* Link 컴포넌트 사용 */}
<div className="bg-white p-6 rounded-lg shadow">
<h2 className="text-xl font-semibold mb-4">Next.js Link</h2>
<Link href="/about" className="text-blue-600 hover:underline">
About 페이지로 (클라이언트 라우팅)
</Link>
<ul className="mt-4 text-sm text-green-600 space-y-1">
<li>✅ 클라이언트 사이드 라우팅</li>
<li>✅ 빠른 페이지 전환</li>
<li>✅ 상태 유지 가능</li>
<li>✅ 자동 프리페칭</li>
</ul>
</div>
</div>
</div>
</div>
) } Link 컴포넌트 기본 사용법 Link 컴포넌트의 다양한 사용 방법을 알아봅시다:
jsx import Link from 'next/link'
export default function BasicLinkUsage() { return (
Link 컴포넌트 사용법
{/* 기본 링크 */}
<div className="bg-white p-4 rounded shadow">
<h3 className="font-semibold mb-2">기본 링크</h3>
<Link href="/">홈으로 가기</Link>
</div>
{/* 스타일 적용 */}
<div className="bg-white p-4 rounded shadow">
<h3 className="font-semibold mb-2">스타일 적용</h3>
<Link
href="/products"
className="bg-blue-600 text-white px-4 py-2 rounded hover:bg-blue-700 inline-block"
>
상품 보러가기
</Link>
</div>
{/* 동적 라우트 */}
<div className="bg-white p-4 rounded shadow">
<h3 className="font-semibold mb-2">동적 라우트</h3>
<div className="space-x-4">
<Link href="/products/1" className="text-blue-600 hover:underline">
상품 1
</Link>
<Link href="/products/2" className="text-blue-600 hover:underline">
상품 2
</Link>
<Link
href={{
pathname: '/products/[id]',
query: { id: '3' }
}}
className="text-blue-600 hover:underline"
>
상품 3 (객체 형식)
</Link>
</div>
</div>
{/* 쿼리 파라미터 */}
<div className="bg-white p-4 rounded shadow">
<h3 className="font-semibold mb-2">쿼리 파라미터</h3>
<Link
href={{
pathname: '/search',
query: {
q: 'next.js',
category: 'tutorial'
}
}}
className="text-blue-600 hover:underline"
>
검색: next.js (카테고리: tutorial)
</Link>
</div>
{/* 해시 링크 */}
<div className="bg-white p-4 rounded shadow">
<h3 className="font-semibold mb-2">해시 링크 (같은 페이지 내 이동)</h3>
<Link href="#section1" className="text-blue-600 hover:underline">
섹션 1로 이동
</Link>
</div>
{/* 외부 링크 */}
<div className="bg-white p-4 rounded shadow">
<h3 className="font-semibold mb-2">외부 링크</h3>
<a
href="https://nextjs.org"
target="_blank"
rel="noopener noreferrer"
className="text-blue-600 hover:underline"
>
Next.js 공식 사이트 (외부 링크는 a 태그 사용)
</a>
</div>
</div>
</div>
) } 프리페칭과 성능 최적화 Link 컴포넌트의 프리페칭 기능을 이해해봅시다:
jsx import Link from 'next/link'
export default function PrefetchingExample() { return (
프리페칭과 최적화
<div className="space-y-6">
{/* 자동 프리페칭 (기본값) */}
<div className="bg-white p-6 rounded-lg shadow">
<h3 className="font-semibold mb-3">자동 프리페칭</h3>
<Link href="/about" className="text-blue-600 hover:underline">
About 페이지 (뷰포트에 보이면 자동 프리페칭)
</Link>
<p className="text-sm text-gray-600 mt-2">
링크가 화면에 보이면 자동으로 페이지를 미리 로드합니다.
</p>
</div>
{/* 프리페칭 비활성화 */}
<div className="bg-white p-6 rounded-lg shadow">
<h3 className="font-semibold mb-3">프리페칭 비활성화</h3>
<Link
href="/heavy-page"
prefetch={false}
className="text-blue-600 hover:underline"
>
무거운 페이지 (프리페칭 OFF)
</Link>
<p className="text-sm text-gray-600 mt-2">
데이터가 많은 페이지는 프리페칭을 비활성화할 수 있습니다.
</p>
</div>
{/* 스크롤 동작 제어 */}
<div className="bg-white p-6 rounded-lg shadow">
<h3 className="font-semibold mb-3">스크롤 동작 제어</h3>
<Link
href="/products"
scroll={false}
className="text-blue-600 hover:underline"
>
상품 페이지 (스크롤 위치 유지)
</Link>
<p className="text-sm text-gray-600 mt-2">
페이지 이동 시 스크롤을 맨 위로 올리지 않습니다.
</p>
</div>
{/* replace 옵션 */}
<div className="bg-white p-6 rounded-lg shadow">
<h3 className="font-semibold mb-3">히스토리 대체</h3>
<Link
href="/login"
replace
className="text-blue-600 hover:underline"
>
로그인 (뒤로가기 시 이전 페이지로)
</Link>
<p className="text-sm text-gray-600 mt-2">
브라우저 히스토리를 대체하여 뒤로가기 동작을 제어합니다.
</p>
</div>
</div>
</div>
</div>
) } 액티브 링크 스타일링 현재 경로와 일치하는 링크에 스타일을 적용하는 방법입니다:
jsx 'use client'
import Link from 'next/link' import { usePathname } from 'next/navigation'
export default function ActiveLinkExample() { const pathname = usePathname()
const navItems = [ { href: '/', label: '홈' }, { href: '/about', label: '소개' }, { href: '/products', label: '제품' }, { href: '/contact', label: '연락처' } ]
return (