[Next.js] - v13.* `next/navigation`

NoowaH·2023년 6월 14일

Changes

넥스트 ^v13.* App 디렉토리를 사용하게 되는 경우 기존 Page 디렉토리에서 사용하던 next/router 를 사용하지 않고 next/navigation을 통해 사용할 수 있게 변경되었다

pageDir:

import { useRouter } from 'next/router'

appDir:

import {
	useRouter,
	usePathname,
	useSearchParams,
	useSelectedLayoutSegment,
	useSelectedLayoutSegments,
	redirect,
	notFound
} from 'next/navigation'

1. useRouter

  • 클라이언트 컴포넌트에서만 사용할 수 있느 훅으로 'use client'필수
  • 기존 next/router에서 사용하던 일부 함수만 사용 가능하며 추가적인 기능도 있다

useRouter` 함수

  • push(href: string) :
    - href 로 클라이언트 사이드 내비게이션
    - 브라우저 히스토리의 스택 추가,
    - 기존 next/routeras, options 사용 불가
    • 🌟 Next.js 라이브러리 내부적으로 Options를 받을 수 있는Parameter 설정은 되어있으나, 문서에도 정보가 없고 구체적인 타입이 명시되어있지 않다 (아마도 추후 업데이트 예정)
  • replace(href: string) :
    - href 로 클라이언트 사이드 내비게이션
    - 브라우저 히스토리의 스택 추가 안함
    - 기존 next/routeras, options 사용 불가
  • refresh() :
    - 현재 라우트 리프레시를 함으로 페이지 재검증기능 구현 가능
    - 데이터 재요청
    - 서버 컴포넌트 리렌더링
  • prefetch(href: string)
    - href에 대한 페이지 prefetch 하여 더욱 빠른 클라이언트 사이드 페이지 전환을 구현할 수 있다
    - next/linkprefetch와 같은 기능을 직접 trigger 할 수 있다는 장점이 있다
  • back(), forward()
    - 브라워 히스토리의 뒤로가기, 앞으로가기

2. usePathname

  • 클라이언트 컴포넌트에서만 사용할 수 있느 훅으로 'use client'필수
  • 현재 URL path를 string으로 반환

usage:

'use client'
 
import { usePathname } from 'next/navigation'
 
const Component = () => {
  const pathname = usePathname()
  ...
}
URLReturned value
//
/posts/posts
/posts?k=v/posts
/posts/some-post/posts/some-post

3. useSearchParams

  • 클라이언트 컴포넌트에서만 사용할 수 있느 훅으로 'use client'필수
  • URL query string의 read-only 버젼을 반환

usage:

'use client'
 
import { useSearchParams } from 'next/navigation'
 
const Component = () => {
  const searchParams = useSearchParams()
  const searchTerm = searchParams.get('searchTerm')
  ...
}
URLsearchParams.get('seachTerm')
/posts?searchTerm=testtest

useSearchParams 함수

  • getAll(name: string) :
    - returns: string[]
    - name의 모든 값을 배열로 반환
  • keys() :
    - returns: string[]
    - query string의 모든 key 값을 배열로 반환
  • values() :
    - returns: string[]
    - query string의 모든 value 값을 배열로 반환
  • entries()
    - returns: Array<[key: string, value: string | string[]]>
  • forEach()
    - returns: Array<string>
  • toString()

4-1. useSelectedLayoutSegment

  • 클라이언트 컴포넌트에서만 사용할 수 있느 훅으로 'use client'필수
  • 현재 active 한 segment의 값을 (/ 가 포함되지 않은) 반환
  • Header Footer와 같이 글로벌하게 사용되는 레이아웃 컴포넌트에서 이를 활용하여 조건부 처리가 가능하다

usage:

'use client'
 
import { useSelectedLayoutSegment } from 'next/navigation'

interface Params {
	slug: string
	children: ReactNode
}

const Component = ({ slug, children } : Params) => {
  const segments = useSelectedLayoutSegment()
  const isActive = slug === segment
  return (
	<Link 
		href={`/posts/${slug}`}
		style={{ fontWeight: isActive ? 'bold' : 'normal' }}
	>		
		{children}
	</Link>
  )
}
LayoutVisited URLReturned segment
app/layout.js/null
app/layout.js/postsposts
app/posts/layout.js/postsnull
app/posts/layout.js/posts/some-postposts
app/posts/layout.jsposts/some-post/editedit

4-2. useSelectedLayoutSegments

  • 클라이언트 컴포넌트에서만 사용할 수 있느 훅으로 'use client'필수
  • 현재 active 한 segment의 값을 (/ 가 포함되지 않은) 문자열 배열로 반환

usage:

'use client'
 
import { useSelectedLayoutSegmentㄴ } from 'next/navigation'

interface Params {
	slug: string
	children: ReactNode
}

const Component = ({ slug, children } : Params) => {
  const segments = useSelectedLayoutSegments()
  ...
}
LayoutVisited URLReturned segment
app/layout.js/[]
app/layout.js/posts[posts]
app/layout.js/posts/some-post[posts, some-post]
app/posts/layout.js/posts[]
app/posts/layout.js/posts/some-post[some-post]

5-1. notFound

  • NEXT_NOT_FOUND에러를 부르며 현 라우트 segment에 대한 렌더링을 끊는다
  • page 디렉토리 getServerSideProps, getStaticProps 를 사용하는 다이나믹 라우팅 페이지에서 에러 발생 시 redirect 내부에 notFound: true 를 활요하여 404 를 띄우는 것과 동일한 역할을 한다

usage:

import { notFound } from 'next/navigation'
 
async function fetchUsers(id) {
  const res = await fetch('https://...')
  if (!res.ok) return undefined
  return res.json()
}
 
const Profile = async({ params }) => {
  const user = await fetchUser(params.id)
 
  if (!user) {
    notFound()
  }
 
  // ...
}

export default Profile

5-2. redirect

  • NEXT_REDIRECT에러를 부르며 현 라우트 segment에 대한 렌더링을 끊는다
  • page 디렉토리 getServerSideProps, getStaticProps 를 사용하는 다이나믹 라우팅 페이지에서 에러 발생 시 redirect 내부에 destination 값을 주어 특정 경로로 리다이렉트 시켜주는 것과 동일한 역할을 한다

usage:

import { redirect } from 'next/navigation'
 
async function fetchTeam(id) {
  const res = await fetch('https://...')
  if (!res.ok) return undefined
  return res.json()
}
 
const Profile = async({ params }) => {
  const team = await fetchTeam(params.id)
  if (!team) {
    redirect('/login')
  }
  // ...
}
profile
조하운

0개의 댓글