[next 13] Linking and Navigating

dana·2023년 7월 8일
0

Next.js

목록 보기
10/13
post-thumbnail

Next.js router는 server-centric routingclient-side navigation를 사용하고 있다.
이런 사용 방식은 즉각적인 로딩 상태동시 렌더링이 가능하도록 해주는데, 이는 클라이언트측의 상태를 보존하고, 비용이 많이 드는 리렌더링을 피하며, 중단이 가능하고 교착상태의 원인이 되지 않도록 한다.

Route로 이동하는 두가지 방법

  1. Link 컴포넌트 사용
  2. useRouter 훅 사용

<Link> 컴포넌트

https://nextjs.org/docs/app/api-reference/components/link
링크 컴포넌트는 리액트의 컴포넌트로 <a> 태그를 확장해 prefetching을 제공하고, 경로간 클라이언트에서의 이동을 지원한다. Next.js에서 경로를 이동하는 기본적인 방법

next/link를 import해서 사용하며 href prop으로 이동 경로를 받는다.

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

동적인 segment에 연결하기

import Link from 'next/link'
 
export default function PostList({ posts }) {
  return (
    <ul>
      {posts.map((post) => (
        <li key={post.id}>
          {* use template literal *}
          <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>
        )
      })}
    </>
  )
}

http://localhost:3000/snippets/search-params?sort=asc&page=2&perPage=100 링크에 있는 경우, pathname은 /snippets/search-params 을 리턴한다.

ID로 이동하기

<Link> 의 기본적인 동작은 변경되는 segment의 상단으로 스크롤 하는 것
href에 id가 명시되어 있다면, 해당 id가 위치한 곳으로 스크롤이 이동
스크롤이 상단으로 올라가는 걸 막고 싶다면, scroll props의 값을 false로 두고 hash(#)된 id 값 넣어주기

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

useRouter() hook

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>
  )
}

훅은 클라이언트단에서만 사용 가능하기 때문에, 가급적 link 컴포넌트 사용해 이동하는 것이 권장됨.

네비게이션 작동 방식

  • 라우트 이동은 link 태그나 router.push()를 이용
  • 라우터는 브라우저 주소창의 URL을 업데이트함
  • 라우터는 클라이언트 캐시에서 변경되지 않은 segment의 재사용을 통해 불필요한 일을 줄이려고 함. (e.g. layout / partial rendering)
  • soft navigation에서는 서버보다 캐시에서 세그먼트 데이터를 가져오지만, hard navigation에서는 서버로 부터 서버 컴포넌트를 받아옴.
    • soft navigation : 탐색 시 탐색 중인 경로에 동적 세그먼트가 포함되어 있지 않거나 현재 경로와 동일한 동적 매개변수가 있는 경우 Next.js는 소프트 탐색을 사용.
      • Navigating from /dashboard/team-red/* to /dashboard/team-red/* will be a soft navigation.
      • Navigating from /dashboard/team-red/* to /dashboard/team-blue/* will be a hard navigation.
  • 생성된 경우 페이로드를 가져오는 동안 서버에서 로딩 UI가 표시됩니다.

클라이언트에서 렌더된 서버컴포넌트 캐싱하기

클라이언트측 캐시는 서버사이드의 Next.js HTTP cache와 다름

새 라우터는 서버컴포넌트의 렌더링된 결과를 갖는 클라이언트 사이드 내부 메모리 캐시를 가집니다. 이 캐시는 route segment에 따라 구분되며, 모든 레벨에서 캐시 만료(무효화)를 허용하고 동시 렌더링 간 일관성을 보장합니다.

user가 앱 내부를 돌아다니면 라우터는 이전 세그먼트와 미리 fetch된 segment 들을 보관합니다. → 서버에서 매번 받아올 필요 X

캐시 유효성 검사

Server Action은 데이터를 필요시에 재확인하기 위한 용도로 사용됨.

  • path 별 : revalidatePath
  • cache tag 별 : revalidateTag

근데 아직 알파 기능

prefetching

해당 페이지에 방문하기 전에 백단에서 미리 로드해놓는 방법
클라이언트 캐시에 캐싱된 값을 렌더링해준다.

Link로 연결된 페이지들은 기본적으로 prefetch

useRouter를 사용하는 경우 prefetch 함수 사용

Static and Dynamic Routes:

  • 경로가 정적인 경우, 세그먼트에 대한 모든 서버 컴포넌트가 prefetch 됨
  • 경로가 동적인 경우, 첫번째 공유 레이아웃부터 첫 loading.js 까지 prefetch.
    • 전체 경로를 동적으로 prefetch하는 데 드는 비용을 줄일 수 있고, 동적 경로에 대한 즉각적인 로딩 상태가 가능해짐

prefetching

  • production에서만 가능
  • <Link>태그에 prefetch={false} 값을 전달해 비활성화 가능

Soft Navigation

해당 세그먼트에 대한 데이터가 캐싱되어 있는 경우, 서버에서 다시 받아오는게 아니라 캐시를 사용

profile
PRE-FE에서 PRO-FE로🚀🪐!

0개의 댓글