- NextJS 에서 경로를 탐색하는 방법
<Link>
컴포넌트 사용useRouter
훅 사용(클라이언트 컴포넌트)redirect
함수 사용(서버 컴포넌트)- 네이티브
Histroy API
사용
1️⃣ <Link>
컴포넌트
<Link>
컴포넌트는 HTML<a>
태그를 확장하여 경로간 prefetching 과 클라이언트 측 탐색을 제공하는 내장 컴포넌트이다.- NextJS에서 경로를 탐색하는 기본적이고 권장되는 방법
next/link
에서 import 하여 사용할 수 있다.- 컴포넌트에 href prop을 전달하여 사용 가능
import Link from 'next/link'
export default function Page() {
return <Link href="/dashboard">Dashboard</Link>
}
2️⃣ useRouter()
훅
- 클라이언트 컴포넌트에서
useRouter
훅을 통해 경로를 변경할 수 있다.
'use client'
import { useRouter } from 'next/navigation'
export default function Page() {
const router = useRouter()
return (
<button type="button" onClick={() => router.push('/dashboard')}>
Dashboard
</button>
)
}
3️⃣ redirect
함수
- 서버 컴포넌트의 경우
redirect
함수를 사용해야 한다. redirect
는 기본적으로 307 상태 코드를 반환한다. 서버 작업에서 사용되는 경우 303을 반환 이는 일반적으로 POST 요청의 결과로 성공 페이지로 리디렉션하는 데 사용된다.redirect
내부적으로 오류가 발생하므로try/catch
블록 외부에서 호출해야 한다.- 렌더링 프로세스 중에 클라이언트 컴포넌트에서 호출할 수 있지만, 이벤트 핸들러에서는 호출할 수 없다. (
useRouter
사용해야함) - 렌더링 프로세스 전에 리디렉션 하고싶다면 next.config.js 또는 Middleware를 사용해야 한다.
import { redirect } from 'next/navigation'
async function fetchTeam(id: string) {
const res = await fetch('https://...')
if (!res.ok) return undefined
return res.json()
}
export default async function Profile({ params }: { params: { id: string } }) {
const team = await fetchTeam(params.id)
if (!team) {
redirect('/login')
}
// ...
}
4️⃣ 네이티브 Histroy API
- 현재 페이지의 URL을 새로운 URL로 변경을 위해 사용함
window.history.pushState
,window.history.replaceState
메서드들은 페이지 리로딩 없이 브라우저 히스토리 스택을 업데이트한다.pushState
,replaceState
호출은 NextJS 라우터에 통합되어usePathname
과useSearchParams
를 동기화 한다.
// window.history.pushState(state,unused,url) => unused 에는 빈 문자열이 들어가야함
// 브라우저의 기록 스택에 새 항목을 추가하는 데 사용
// 사용자는 이전 상태로 돌아갈 수 있다.
'use client'
import { useSearchParams } from 'next/navigation'
export default function SortProducts() {
const searchParams = useSearchParams()
// 제품 목록 정렬
function updateSorting(sortOrder: string) {
const params = new URLSearchParams(searchParams.toString())
params.set('sort', sortOrder)
window.history.pushState(null, '', `?${params.toString()}`)
}
return (
<>
<button onClick={() => updateSorting('asc')}>Sort Ascending</button>
<button onClick={() => updateSorting('desc')}>Sort Descending</button>
</>
)
}
// window.history.replaceState(state, unused, url)
// 브라우저의 기록 스택에서 현재 항목을 대체하는 데 사용
// 사용자는 이전 상태로 돌아갈 수 없다.
'use client'
import { usePathname } from 'next/navigation'
export function LocaleSwitcher() {
const pathname = usePathname()
// locale을 전환
function switchLocale(locale: string) {
// e.g. '/en/about' or '/fr/contact'
const newPath = `/${locale}${pathname}`
window.history.replaceState(null, '', newPath)
}
return (
<>
<button onClick={() => switchLocale('en')}>English</button>
<button onClick={() => switchLocale('fr')}>French</button>
</>
)
}
5️⃣ 라우팅 및 탐색 작동 방식
- App Roter는 라우팅과 탐색에 하이브리드 방식 사용
- 서버에서 애플리케이션 코드는 경로 세그먼트별로 자동으로 코드 분할 된다.
- Next.js는 경로 세그먼트를 prefetch 하고 캐시한다.
- 따라서 사용자가 새 경로로 탐색할 때 브라우저는 페이지를 다시 로드하지 않고 변경된 경로 세그먼트만 다시 렌더링하여 탐색 경험과 성능을 개선한다.
- 📌 코드 분할
- 코드를 더 작은 번들로 분할하여 브라우저에서 다운로드하고 실행할 수 있다.
- 이렇게 하면 각 요청에 대해 전송되는 데이터 양과 실행 시간이 줄어들어 성능이 향상된다.
- 서버 컴포넌트를 사용하면 애플리케이션 코드를 경로 세그먼트별로 자동으로 코드 분할할 수 있다. => 현재 경로에 필요한 코드만 탐색에 로드된다.
- 📌 prefetching
- 사용자가 경로를 방문하기 전에 백그라운드에서 경로를 미리 로드하는 방법
- Nextjs에서 경로를 prefetch 하는 방법
<Link>
컴포넌트: 브라우저의 Viewport 내에 있으면 Link의 경로에 해당하는 페이지를 백그라운드에서 미리 가져온다. (prefetch는 개발 환경이 아닌 프로덕션 환경에서만 가능하다)router.prefetch()
:useRouter
훅은 프로그래밍 방식으로 경로를 미리 가져오는 데 사용할 수 있다. 특정 사용자 상호작용 이후에 특정 경로를 미리 로드하고자 할 때 유용하다.
- 📌 캐싱
- NextJS에는 Router Cache 라는 메모리 내 클라이언트 측 캐시가 있다.
- 사용자가 앱을 탐색할 때 미리 가져온 경로 세그먼트와 방문한 경로의 React Server Component Payload가 캐시에 저장된다.
- 탐색 시 서버에 새로운 요청을 하는 대신 캐시를 최대한 재사용하여 요청 수와 전송되는 데이터 수를 줄여 성능을 향상 시킨다.
- 📌 부분 렌더링
- 탐색 중에 변경되는 경로 구간만 클라이언트에서 다시 렌더링되고, 공유되는 구간은 보존된다는 것을 의미한다.
- 부분 렌더링이 없다면 각 탐색은 클라이언트에서 전체 페이지를 다시 렌더링하게 된다.
- 변경되는 세그먼트만 렌더링하면 전송되는 데이터 양과 실행 시간이 줄어들어 성능이 향상된다.
- ex) /blog/[slug]/page, /blog/first/, blog/second 의 경로가 있다고 했을때, /blog 의 하위 요소인 부분들은 blog layout 이라는 공유 layout이 유지된다.
- 📌 소프트 네비게이션
- 브라우저는 페이지 간 이동시에 "하드 탐색"을 수행한다.
- 하지만 NextJS 앱 라우터는 페이지 간에 "소프트 탐색"을 활성화하여 부분 렌더링할 수 있게 한다.
- 따라서 탐색 중에 클ㄹ이언트 React 상태를 보존할 수 있다.
- 📌 뒤로 및 앞으로 탐색
- 기본적으로 NextJS는 앞뒤 탐색을 위한 스크롤 위치를 유지하고 라우터 캐시에 있는 경로 세그먼트를 재사용한다.
📚 REFERENCE
https://nextjs.org/docs/app/building-your-application/routing/linking-and-navigating
https://developer.mozilla.org/en-US/docs/Web/API/History/pushState
https://developer.mozilla.org/en-US/docs/Web/API/History/replaceState
'FE > NextJS' 카테고리의 다른 글
NextJS 공식문서 파헤치기 (Middleware) (1) | 2024.12.17 |
---|---|
NextJS 공식문서 파헤치기 (Error Handling) (0) | 2024.12.10 |
NextJS 공식문서 파헤치기 (Caching) (1) | 2024.11.15 |
NextJS 공식문서 파헤치기 (Defining Routes, Pages, Layouts and Templates) (1) | 2024.11.14 |
NextJS 공식문서 파헤치기 (Routing Fundamentals) (1) | 2024.11.13 |