Next.js App Router에 대해 알아보자(4. 링크와 네비게이션)

한상욱·2023년 9월 9일
1

Next.js 13 기초

목록 보기
4/6

next.js에서 재공하는 내장 컴포넌트로 a태그처럼 동작합니다. 프리 패치를 제공하고 라우터 간 클라이언트 사이드 네비게이션을 지원합니다. Next.js에서 라우트 간 이동은 Link로 한다고 생각하면 편합니다.

import Link from 'next/link'
 
export default function Page() {
  return <Link href="/dashboard">Dashboard</Link>
}

href속성은 필수로 넣어주어야 합니다. Link가 이동하는 경로이기 때문입니다. 그 외에 속성은 다음을 참조하세요.

동적 라우팅도 지원합니다. 아래와 같이 다이나믹한 세그먼트를 사용하면 됩니다. 커머스 상품 페이지나 블로그 포스트에서 사용하면 좋을 것 같습니다.

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()을 사용하면 됩니다. 선택된 태그 다른 UI 보여주기에 활용하면 좋을 것 같습니다.

'use client'
 
import { usePathname } from 'next/navigation'
import Link from 'next/link'
 
export function Navigation({ navLinks } : { navLinks: string[]}) {
  const pathname = usePathname()
 
  return (
    <>
      {navLinks.map((link) => {
        const isActive = pathname === link.href
 
        return (
          <Link
            className={isActive ? 'text-blue' : 'text-black'}
            href={link.href}
            key={link.name}
          >
            {link.name}
          </Link>
        )
      })}
    </>
  )
}

id를 이용한 스크롤도 Link를 쓰면 쉽습니다.

<Link href="/dashboard#settings">Settings</Link>

Next.js 앱 라우터의 기본 동작은 앞뒤로 페이지 이동 시 스크롤 위치를 유지하는 것과 새로운 페이지에서 스크롤의 위치를 꼭대기로 올리는 것입니다. 이게 싫으면 scroll 속성을 false로 주면 됩니다. useRouter()를 이용하면 useRouter()에서 나온 객체를 push할 때 scroll의 속성을 false로 주면 됩니다.

// next/link
<Link href="/dashboard" scroll={false}>
  Dashboard
</Link>

// useRouter
import { useRouter } from 'next/navigation'
 
const router = useRouter()
 
router.push('/dashboard', { scroll: false })

2. useRouter

Link 태그를 이용하지 않고 특정 컴포넌트를 눌렀을 때 라우팅을 원하면 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>
  )
}

useRouter()를 더 알고 싶으면 다음으로 이동하세요.

3. 어떻게 라우팅와 네비게이션이 동작을 하는건가?

앱 라우터는 라우팅과 네비게이션에 하이브리드한 접근 방법을 사용합니다. 서버에서는 애플리케이션을 구성하는 코드가 라우터의 세그먼트에 따라 자동으로 분산이 됩니다. 클라이언트에서는 라우터의 세그먼트를 prefetch나 캐시로 사용니다. 이 말은 유저가 새로운 경로로 접근하면 브라우저는 새로운 페이지를 불러오지 않는다는 것이고 변경된 경로 세그먼트만 다시 렌더링하여 탐색 경험과 성능을 향상 시킨다는 것입니다.

Prefetching

유저가 페이지를 방문하기 전, 미리 페이지를 만드는 것입니다.

Next.js에서 prefetch하는 법은 다음과 같습니다.

  • Link 컴포넌트: 라우트는 유저에게 뷰포트가 보이기 전 자동으로 prefetch를 합니다. prefetching은 페이지가 처음 불려지거나 스크롤링을 통해서 보여질 때 발생합니다.
  • router.prefetch(): useRouter() 훅에서 제공하는 함수입니다.

링크 컴포넌트의 prefetch는 정적 라우트와 동적 라우트에 따라서 달라집니다.

  • 정적 라우팅: prefetch가 기본 값이 true입니다. 모든 라우팅은 prefetch되고 캐시됩니다.
  • 동적 라우팅: prefetch가 자동으로 발생합니다. 첫 번째 loading.js 파일이 prefetch되어 30초 동안 캐시될 때까지 공유 레이아웃만 다운됩니다.이것은 fetching의 비용과 전체 동적 라우팅에 들어가는 비용을 감소시키고 유저에게 즉시 로딩 상태를 제공해 더 나은 시작적인 피드백을 제공할 수 있습니다.

prefetch 발생이 싫으면 옵션으로 false를 주면 됩니다.

Caching

Next.js는 라우터 캐시라고 불리는 인 메모리 클라이언트 캐시를 가지고 있습니다. 유저가 앱 내부를 탐색할 때 미리 가져온 라우트 세그먼트와 방문한 경로의 리액트 서버 컴포넌트의 구성 소 페이로드가 캐시에 저장이 됩니다.

이 말은 탐색 시, 서버에 새로운 요청을 하는 대신 최대한 캐시를 재사용 한다는 것을 말하고 요청 수와 전송되는 데이터 수를 줄여 성능을 향상한다는 의미입니다.

Partial Rendering

부분 렌더링의 의미는 공유된 세그먼트는 다시 불러오지 않고 변경된 세그먼트만 다시 불러온다는 말입니다. 예를 들어 /dashboard/settings/dashboard/analytics가 있다면 /dashboard가 제공하는 레이아웃은 재사용하고 /setting/analytics의 부분은 새로 불러온다는 것입니다.

부분 렌더링이 없으면 모든 페이지가 재호출 될 때 서버에서 모든 부분을 새로 그릴 것입니다. 공유된 부분은 그대로 사용하고 변경된 부분만 새롭게 그리는 것이 서버의 자원을 아끼는 데 매우 도움이 됩니다.

Soft Navigation

기본적으로 브라우저는 페이지간 하드 네비게이션으로 동작합니다. 이 말은 브라우저는 모든 페이지를 다시 불러오고 React의 상태를 모두 리셋시킨다는 것을 말합니다. 그러나 Next.js App Router는 소프트 네비게이션을 제공합니다. 이 말은 리액트가 React와 브라우저 상태를 유지하면서 변경된 세그먼트만 렌더링하며 전체 페이지를 다시 로드하지 않는다는 것을 말합니다.

Back and Forward Navigation

기본적으로 Next.js는 스크롤 위치를 앞뒤로 페이지 전환할 때 유지합니다. 그리고 라우터 세그먼트를 라우터 캐시로 재사용합니다.

profile
그냥 뛰는 사람

0개의 댓글