현인
Next.js 튜토리얼 - 5장 페이지 네비게이팅 본문
이전 장에서 대시보드 레이아웃과 페이지들을 만들었다. 이제 사용자가 대시보드 경로 사이를 라우팅할 수 있도록 몇 가지 링크를 추가해보자
5장에서 다룰 내용
- next/link 컴포넌트 사용법
- usePathname() 훅 사용하여 활성 링크 표기 방법
- Next.js에서 네비게이팅(Navigating)이 이뤄지는 방식
왜 네비게이팅을 최적화 해야 할까?
페이지 간에 링크를 구현하려면 HTML <a> 엘리먼트를 사용한다. 현재 사이드바 링크는 <a> 엘리먼트를 사용하지만 브라우저에서 홈, invoice 및 customer 페이지 사이를 탐색할 때 어떤 일이 일어나는지 보자.
각 페이지 이동 시 전체 페이지가 새로고침 된다.
<Link> 컴포넌트
Next.js에서는 <Link> 컴포넌트를 사용하여 어플리케이션의 페이지간 링크를 구현할 수 있으며 JavaScript로 클라이언트 측 네비게이팅이 가능하다.
<Link> 컴포넌트를 사용해보기 위해 /app/ui/dashboard/nav-links.tsx 파일을 열고 next/link 라이브러리에 있는 Link 컴포넌트를 import 해보자. 그리고 <a> 태그를 <Link> 태그로 교체해보자.
import {
UserGroupIcon,
HomeIcon,
DocumentDuplicateIcon,
} from '@heroicons/react/24/outline';
import Link from 'next/link';
// ...
export default function NavLinks() {
return (
<>
{links.map((link) => {
const LinkIcon = link.icon;
return (
<Link
key={link.name}
href={link.href}
className="flex h-[48px] grow items-center justify-center gap-2 rounded-md bg-gray-50 p-3 text-sm font-medium hover:bg-sky-100 hover:text-blue-600 md:flex-none md:justify-start md:p-2 md:px-3"
>
<LinkIcon className="w-6" />
<p className="hidden md:block">{link.name}</p>
</Link>
);
})}
</>
);
}
보시다시피 Link 컴포넌트는 <a> 태그와 사용법이 비슷하다. 단, <a href="…"> 대신 <Link href="…">를 사용한다.
변경사항을 저장하고 localhost에서 작동하는지 확인해보자. 이제 전체 페이지 새로고침 없이 페이지 간 이동이 가능할 것이다. 애플리케이션의 일부가 서버에서 렌더링되지만, 전체 페이지 새로고침이 없어 웹 앱처럼 느껴질 것이다. 왜 그럴까?
자동 코드 분할과 Prefetching
Next.js는 네비게이션 경험을 개선하기 위해 라우트 세그먼트별로 애플리케이션 코드를 자동으로 분할한다. 이는 브라우저가 초기 로드 시 모든 애플리케이션 코드를 불러오는 전통적인 React SPA와는 다른 방식이다.
라우트별 코드 분할은 페이지를 독립적으로 만든다. 특정 페이지에서 오류가 발생해도 애플리케이션의 나머지 부분은 계속 작동한다.
게다가 프로덕션 환경에서는 <Link> 컴포넌트가 브라우저의 뷰포트에 나타날 때마다 Next.js가 자동으로 연결된 라우트의 코드를 백그라운드에서 프리페치한다. 사용자가 링크를 클릭할 때쯤이면 목적지 페이지의 코드가 이미 백그라운드에서 로드되어 있어 페이지 전환이 거의 즉각적으로 이루어진다!
네비게이션 작동 방식에 대해 자세히 알아보자.
패턴: 활성 링크 표시하기
사용자에게 현재 위치한 페이지를 알려주기 위해 활성 링크를 표시하는 것은 일반적인 UI 패턴이다. 이를 구현하려면 URL에서 사용자의 현재 경로를 가져와야 한다. Next.js는 usePathname()이라는 훅을 제공하여 경로를 확인하고 이 패턴을 구현할 수 있게 해준다.
usePathname()은 훅이기 때문에 nav-links.tsx 파일을 클라이언트 컴포넌트로 변환해야 한다. 파일 상단에 React의 "use client" 지시어를 추가하고, next/navigation에서 usePathname()을 import 해보자.
'use client';
import {
UserGroupIcon,
HomeIcon,
InboxIcon,
} from '@heroicons/react/24/outline';
import Link from 'next/link';
import { usePathname } from 'next/navigation';
// ...
다음으로, NavLinks 컴포넌트에 pathname이라고 불리는 변수를 만들고, path를 할당한다.
export default function NavLinks() {
const pathname = usePathname();
// ...
}
CSS 스타일링 챕터에서 소개했던 clsx 라이브러리를 사용하면 활성화된 링크에 조건부 클래스 네임을 설정할 수 있다. 만약 link.href 가 pathname과 같다면, 해당 링크는 연한 파란색 배경에 파란색 텍스트로 표시되어야 한다.
최종 코드는 다음과 같다.
'use client';
import {
UserGroupIcon,
HomeIcon,
DocumentDuplicateIcon,
} from '@heroicons/react/24/outline';
import Link from 'next/link';
import { usePathname } from 'next/navigation';
import clsx from 'clsx';
// ...
export default function NavLinks() {
const pathname = usePathname();
return (
<>
{links.map((link) => {
const LinkIcon = link.icon;
return (
<Link
key={link.name}
href={link.href}
className={clsx(
'flex h-[48px] grow items-center justify-center gap-2 rounded-md bg-gray-50 p-3 text-sm font-medium hover:bg-sky-100 hover:text-blue-600 md:flex-none md:justify-start md:p-2 md:px-3',
{
'bg-sky-100 text-blue-600': pathname === link.href,
},
)}
>
<LinkIcon className="w-6" />
<p className="hidden md:block">{link.name}</p>
</Link>
);
})}
</>
);
}
각 메뉴를 클릭했을 때 활성 링크가 잘 표시되는지 확인해보자.
마치며
React에서는 path를 찾기 위해 직접 훅을 만들거나 일일히 가져왔었는데, usePathname 훅이 있어서 pathname을 가져오는 작업이 수월해서 좋았다. 또 <Link> 컴포넌트를 제공하여 네비게이팅 최적화도 쉽다.
학습 자료
https://nextjs.org/learn/dashboard-app/navigating-between-pages
'기술 학습 > NextJS' 카테고리의 다른 글
캐시 데이터로 에러 발생 시 데이터 유지 (0) | 2024.11.29 |
---|---|
[Next.js] 동적 렌더링 최적화하기 (1) | 2024.11.25 |
Next.js 튜토리얼 - 4장 레이아웃 및 페이지 만들기 (1) | 2024.11.15 |
Next.js 튜토리얼 - 3장 폰트 및 이미지 최적화 (4) | 2024.11.08 |
Next.js 튜토리얼 - 2장 CSS 스타일링 (1) | 2024.11.06 |