Next.js 라우터는 클라이언트 측 navigating과 서버 중심 라우팅을 사용합니다. 즉각적인 로딩 상태와 동시 랜더링을 지원합니다. 즉, navigating은 클라이언트 측 상태를 유지하고 비용이 많이 드는 리랜더링을 피하고, 중단이 가능하며 race condition을 일으키지 않습니다.
Navigaiting을 하는 방법은 두 가지가 제공됩니다.
<Link>
컴포넌트
useRoute
훅
<Link>
컴포넌트는 HTML의 <a>
태그를 확장하여 라우트 간 prefetching과 클라이언트 측 navigation을 제공합니다. Next.js에서 navigating을 하는 주요 방법입니다.
<Link>
컴포넌트를 사용하기 위해서는 next/link
에서 컴포넌트를 import
한 뒤, herf
프로퍼티을 전달하면 됩니다.
import Link from 'next/link'
export default function Page() {
return <Link href="/dashboard">Dashboard</Link>
}
href
이동할 경로 혹은 URL입니다.
tpye | required |
---|---|
String or Object | true |
<Link
href={{
pathname: '/about',
query: { name: 'test' },
}}
>
About
</Link>
replace
기본값은 false
입니다. true
로 지정하면 next/link
는 현재 History 상태 스택에 새로운 URL을 추가하는 대신 현재 History 상태를 대체합니다.
tpye | required |
---|---|
boolean | false |
import Link from 'next/link'
export default function Page() {
return (
<Link href="/dashboard" replace>
Dashboard
</Link>
)
}
prefetch
기본값은 true
입니다. true
인 경우, next/link
는 백그라운드에서 페이지를 미리 가져오게 됩니다. 이는 클라이언트 측 navigating 성능을 개선하는데 유용합니다. 뷰포트이 모든 <Link>
는 미리 로드됩니다.
tpye | required |
---|---|
boolean | false |
import Link from 'next/link'
export default function Page() {
return (
<Link href="/dashboard" prefetch={false}>
Dashboard
</Link>
)
}
동적 Segments에 연결할 때, 탬플릿 리터럴 등을 사용하여 링크 목록을 생셩할 수 있습니다.
import Link from 'next/link'
export default function PostList({ posts }) {
return (
<ul>
{posts.map((post) => (
<li key={post.id}>
<Link href={`/blog/${post.slug}`}>{post.title}</Link>
</li>
))}
</ul>
)
}
usePathname()
을 사용하여 링크가 활성 상태인지 확인할 수 있습니다.
'use client'
import { usePathname } from 'next/navigation'
import { Link } from 'next/link'
export function Navigation({ navLinks }) {
const pathname = usePathname()
return (
<>
{navLinks.map((link) => {
const isActive = pathname.startsWith(link.href)
return (
<Link
className={isActive ? 'text-blue' : 'text-black'}
href={link.href}
key={link.name}
>
{link.name}
</Link>
)
})}
</>
)
}
<Link>
의 기본 동작은 변경된 route segment의 상단으로 스크롤하는 것입니다. 이때 herf
에 정의된 ID가 있다면 일반 <a>
태그와 유사하게 특정 ID로 스크롤 됩니다.
useRouter
훅은 사용하면 클라이언트 컴포넌트 내에서 프로그래밍 방식으로 라우트를 변경할 수 있습니다. useRouter
를 사용하려면 next/navigation
에서 import
한 후, 클라이언트 컴포넌트 내부에서 사용하면 됩니다.
'use client'
import { useRouter } from 'next/navigation'
export default function Page() {
const router = useRouter()
return (
<button type="button" onClick={() => router.push('/dashboard')}>
Dashboard
</button>
)
}
router.push(herf : string)
: 제공된 라우트로 클라이언트 측 navigating을 수행합니다. 브라우저의 히스토리 스택에 새 항목을 추가합니다.
router.replace(herf : string)
: 브라우저의 히스토리 스택에 새 항목을 추가하지 않고 제공된 경로로 클라이언트 측 탐색을 수행합니다.
router.refresh()
: 현재 경로를 새로 고칩니다. 서버에 새 요청을 하고, 데이터 요청을 다시 가져오고, 서버 컴포넌트를 다시 랜더링합니다. 클라이언트는 영향을 받지 않는 클라이언트 측 React 상태 또는 브라우저 상태를 잃지 않고 업데이트된 React 서버 컴포넌트 페이로드와 병합합니다.
router.back()
: soft navigation을 사용하여 브라우저의 히스트리 스택에서 이전 경로로 이동합니다.
router.forward()
: soft navigation을 사용하여 브라우저의 히스트리 스택에서 다 경로로 이동합니다.
<Link>
를 사용하거나 router.push()
를 호출하여 경로 전환이 시작됩니다.
라우터는 브라우저 주소 표시줄에서 URL을 업데이트합니다.
라우터는 클라이언트 측 캐시에서 변경되지 않은 세그먼트를 재사용하여 불필요한 작업을 피합니다. 이를 부분 랜더링이라고 합니다.
soft navigation 조건이 충족되면 라우터는 서버가 아닌 캐시에서 새 새그먼트를 가져옵니다. 그렇지 않은 경우 라우터는 hard navigation을 수행하고 서버에서 컴포넌트 페이로드를 가져옵니다.
생성된 경우 페이로드를 가져오는 동안 서버에서 로딩 UI가 표시됩니다.
라우터는 캐시된 페이로드 또는 새로운 페이로드를 사용하여 클라이언트에서 새 새그먼트를 랜더링합니다.
새 라우터에는 서버 컴포넌트의 랜더링 결과를 저장하는 인메모리 클라이언트 측 캐시가 있습니다. 캐시는 route segments 별로 분할되어 어느 수준에서든 무효화가 가능하며 동시 랜더링 전반에서 일관성을 보장합니다.
사용자가 앱을 탐색할 때 라우터는 이전에 가져온 세그면트와 미리 가져온 세그먼트의 페이로드를 캐시에 저장합니다.
즉, 특정 경우에 라우터는 서버에 새로 요청하는 대신 캐시를 재사용할 수 있습니다. 이렇게 하면 데이터를 다시 가져오고 불필요한 컴포넌트를 다시 랜더링하지 않아도 되므로 성능이 향상됩니다.
Server Action은 경로 또는 캐시 태그를 기준으로 온디맨드 데이터를 재검증할 수 있습니다.
Prefetching은 라우트에 방문하기 전에 백그라운드에서 미리 로드하는 방식입니다. prefetching 된 경로의 랜더링 겨로가는 클라이언트 측 캐시에 추가됩니다. 이렇게 하면 prefetching된 경로로 거의 즉시 이동할 수 있습니다.
기본적으로 라우트는 <Link>
컴포넌트를 사용할 때 뷰포트에 표시되는 대로 Prefetching됩니다. 페이지가 처음 로드될 때, 스크롤할 떄 발생할 수 있습니다. useRouter()
훅의 prefetch
메서드를 사용하여 프로그래밍 방식으로 라우트를 Prefetching 할 수 있습니다.
라우트가 정적 라우트인 경우, Route Segment에 대한 모든 서버 컴포넌트 페이로드가 프리패치 됩니다.
라우트가 동적 라우트인 경우, 첫 번쨰 공유 레이아웃부터 첫 번째 loading.js 파일까지 페이로드가 프리패치됩니다. 이렇게 하면 전체 라우트를 동적으로 프리패치하는 데 드는 비용이 줄어들고 동작 라우트에 대한 로딩 상태를 즉시 확인할 수 있습니다.
내비게이션에서 변경된 세그먼트에 대한 캐시가 재사용되며 서버에 새로운 데이터를 요청합니다.
탐식 시 탐색 중인 라우트에 동적 세그먼트가 포함되어 있지 않거나 현재 경로와 동일한 동적 매개변수 있는 경우 Next.js는 Soft Navigation을 사용합니다.
탐색 시 캐시가 무효화되고 서버가 데이터를 새로 고침하여 변경된 세그먼트를 다시 랜더링됩니다.
뒤로 / 앞으로 탐색은 Soft Navigaton으로 동작합니다. 즉, 클라이언트 측 캐시가 재사용되고 즉각적으로 이동합니다.
기본적으로 Next.js 탐색에서 변경된 세그먼트를 보기 위해 포커스를 설정하고 스크롤합니다.