Next.js 13 - 1. Routing - 1.4. Linking and Navigating

Chaewon Kang·2023년 4월 24일
0

Linking and Navigating (링크와 네비게이션 활용하기)

Next.js의 라우터는 클라이언트 사이드 네비게이션과 함께, 서버 중심적 라우팅을 사용합니다. 이는 즉각적인 로딩 상태동시 렌더링을 지원합니다. 즉, 네비게이션은 클라이언트 측 상태를 유지하며, 무거운 리렌더를 피하고, 중단 가능하며, 레이스 컨디션(race conditions)를 일으키지 않는다는 것을 의미합니다.

루트 간 네비게이션을 위한 두 가지 방법이 있습니다:

  • <Link> 컴포넌트
  • useRouter

해당 페이지에서는 <Link>useRouter()을 어떻게 사용하는지 알아보고, 네비게이션이 어떻게 동작하는지 더 깊이 이해해 봅시다.

<Link>는 프리페치와 루트 간의 클라이언트 사이드 네비게이션을 제공하기 위해 만들어진, HTML의 <a> 태그를 확장한 리액트 컴포넌트입니다.이는 Next.js 안에서 루트 간 네비게이팅을 지원하는 가장 주요한 방법입니다.

Usage (사용 방법)

// app/page.tsx

export default function Page() {
	return <Link href="/dashboard">Dashboard</Link>;
}

<Link>에 넘길 수 있는 다른 선택적인 props 들이 있습니다. 더 많은 정보는 API 레퍼런스를 참조하세요.

Example: Linking to Dynamic Segment (동적 루트 세그먼트에 연결하기)

동적 세그먼트에 연결할 때는, 링크 리스트를 생성하기 위해 템플릿 리터럴과 인터폴레이션을 사용할 수 있습니다.예를 들어, 블로그 포스트 리스트를 생성하기 위해서는 아래와 같이 할 수 있습니다.

// app/blog/PostList.jsx

export default function PostList({ posts }) {
	return (
    	<ul>
        	{posts.map((post) => (
            	<li key={post.id}>
                	<Link href={`/blog/${post.slug}`}>
                    	{post.title}
                    </Link>
                </li>
            ))}
        </ul>
    )
}

useRouter() Hook (useRouter() 훅)

useRouter 훅은 클라이언트 컴포넌트 안에서 프로그래머틱하게 루트를 변경할 수 있도록 도와줍니다.

useRouter 훅을 사용하기 위해서는, next/navigation에서 임포트하고, 클라이언트 컴포넌트 안에서 해당 훅을 호출하면 됩니다.

'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훅은 push(), refresh()와 같은 메서드들을 지원합니다. 더 많은 정보는 API 레퍼런스를 확인하세요.

추천: 특별히 useRouter을 이용해야 할 이유가 없다면, 루트 간 네비게이팅을 위해 Link 컴포넌트를 사용하세요.

How Navigation Works (네비게이션은 어떻게 동작할까요)

  • 루트 전환은 <Link> 컴포넌트를 이용하거나 router.push() 메서드를 호출해서 촉발됩니다.
  • 라우터는 브라우저의 주소창을 업데이트합니다.
  • 라우터는 클라이언트 캐시로부터, 변화하지 않은 세그먼트 (예를 들면 공유된 레이아웃)들을 재사용함으로써 불필요한 과업을 수행하는 것을 방지합니다. 이는 부분적인 렌더링으로 간주되기도 합니다.
  • 소프트 네비게이션의 조건들이 만족되면, 서버보다는 캐시로부터 새로운 세그먼트를 페치합니다. 아닌 경우에는 라우터는 하드 네비게이션을 수행하고 서버로부터 서버 컴포넌트의 페이로드를 가져옵니다.
  • 로딩 UI가 생성된 경우에, 페이로드가 페치되는 도중에 서버로부터 로딩 UI가 보여집니다.
  • 라우터는 클라이언트에 새로운 세그먼트를 렌더하기 위해 캐싱된 페이로드나 새로운 페이로드를 사용합니다.

Client-side Caching of Rendered Server Components (렌더된 서버 컴포넌트의 클라이언트 사이드 캐싱)

알아두면 좋은 것: 클라이언트 사이드 캐시는 서버 사이드 Next.js HTTP 캐시와는 다릅니다.

새로운 라우터는 인-메모리 클라이언트 사이드 캐시를 가지고 있으며, 이는 서버 컴포넌트 (페이로드)의 렌더링 결과물을 저장합니다. 이 캐시는 루트 세그먼트에 의해 분할되고, 어떤 레벨에서든 무효화를 지원하며, 동시에 발생하는 렌더들 사이에 일관성을 보장합니다.

유저가 앱을 탐방할 때, 라우터는 이전에 페치한 세그먼트의 페이로드와 캐시에서 프리페치한 세그먼트를 저장할 것입니다.

이는 특정한 상황에서, 라우터가 서버에 새로운 요청을 보내는 대신 캐시를 재사용할 수 있음을 뜻합니다. 불필요한 컴포넌트의 리렌더나 데이터를 다시 가져오는 것을 피하면서, 퍼포먼스를 향상시킬 수 있습니다.

Invalidating the Cache (캐시 무효화)

router.refresh()를 이용해서 루트를 새로고침 할 수 있습니다. 이는 서버에 새로운 요청을 만들고, 데이터 리퀘스트를 새로 가져오며 서버 컴포넌트를 리렌더링합니다. 더 많은 정보는 API 레퍼런스를 참조하세요. 추후에는 뮤테이션의 경우 자동으로 캐시를 무효화하게 될 겁니다.

Prefetching (프리페칭)

프리페칭은 유저가 방문하기 전에 백그라운드에서 루트를 미리 로드하는 방법입니다. 프리페치 된 루트들의 렌더링 결과물은 라우터의 클라이언트 사이드 캐시에 저장됩니다. 이는 프리페칭된 루트에 거의 즉각적으로 네비게이팅 할 수 있도록 만들어 줍니다.

기본적으로 <Link> 컴포넌트를 이용했을 경우, 뷰포트 안에서 보여지게 될 때 루트들은 프리페치 됩니다. 이는 페이지가 가장 처음 로드될 때나 스크롤을 통해서 일어날 수 있습니다. 루트들은 또한 useRouter() 훅prefetch 메서드를 통해 프로그래머틱하게 프리페치 될 수 있습니다.

정적/동적 루트들:

  • 만약 루트가 정적이라면, 루트 세그먼트들의 모든 서버 컴포넌트 페이로드들이 프리페치 될 겁니다.
  • 만약 루트가 동적이라면, 가장 첫 공유 레이아웃으로부터 가장 첫 loading.js파일의 페이로드가 프리페치 될 겁니다. 이는 모든 루트를 동적으로 프리페칭하는 것의 비용을 줄여주며, 동적 루트들에서 즉각적인 로딩 상태를 만들 수 있게 도와줍니다.

알아두면 좋은 것:

  • 프리페칭은 프로덕션 레벨에서만 활성화 될 수 있습니다.
  • 프리페칭은 <Link> 컴포넌트에서 prefetch={false}를 넘겨서 비활성화 할 수 있습니다.

Hard Navigation (하드 네비게이션)

네비게이션에서, 캐시는 무효화되고 서버는 데이터를 다시 가져오며, 변경된 세그먼트를 리렌더링 합니다.

Soft Navigation (소프트 네비게이션)

네비게이션에서, 변경된 세그먼트의 캐시가 존재할 경우 재사용되며, 데이터를 가져오기 위해 서버에 새로운 요청을 만들지 않습니다.

Conditions for Soft Navigation (소프트 네비게이션을 위한 조건들)

네비게이션에서, 이동하고 있는 라우트가 프리페치 되고 있는 와중이고, 동적 세그먼트나 현재 라우트와 동일한 동적 파라미터를 포함하고 있지 않은 상태라면 Next.js는 소프트 네비게이션을 사용할 것입니다.

예를 들어, [team] 이라는 동적 세그먼트를 포함하고 있는 다음과 같은 루트를 상상해 봅시다: /dashboard/[team]/*. 만약 [team] 파라미터가 변경되면, /dashboard/[team]/* 하위의 캐싱된 세그먼트들만 무효화 될 겁니다.

  • /dashboard/team-red/* 에서 /dashboard/team-red/* 로의 이동은 소프트 네비게이션입니다.
  • /dashboard/team-red/*에서 /dashboard/team-blue/* 로의 이동은 하드 네비게이션입니다.

Back/Forward Navigation (이전/다음 네비게이션)

이전/다음 네비게이션 (popstate 이벤트)는 소프트 네비게이션 행동 양식을 갖고 있습니다. 이는, 클라이언트 사이드 캐시가 재사용되며, 네비게이션이 거의 즉각적이라는 뜻입니다.

Focus and Scroll Management (포커싱과 스크롤 관리)

기본적으로, Next.js는 네비게이션을 통해 변화한 세그먼트 뷰에 포커스와 스크롤을 적용합니다. 이러한 접근성과 사용성 기능은 향상된 라우팅 패턴이 적용되었을 때 더욱 명백하게 중요해집니다.

profile
문학적 상상력과 기술적 가능성

0개의 댓글