22sook00 logo
SookDev

Next.js Routing

tag
next.js
productivity
date
Jul 10, 2022
Next.js 는 pages 라는 디렉토리를 만들면 자동적으로 라우터가 빌드된다.

Index routes

ex ) pages 안에 index.js → 경로가 / 로 끝나고 (like react-router 의 exact path = '/' 와 같은 역할)
pages/example/index.js → '/example' 라는 경로로 작성되게 된다. (like path = '/example')

Nested routes

index.js 로 작성하지 않고 .js 파일명을 따로 만들면 다음과 같이 라우트가 명시된다.
ex ) pages/example/first.js → '/example/first'
pages/dashboard/settings/username.js → '/dashboard/settings/username'

Dynamic route segments (동적 라우팅)

일반 정적 라우팅이 아닌, 파라미터에 의해 변경되는 라우터 필요시
대괄호를 작성하여 라우터와 파라미터를 일치시킬 수 있다.
ex) pages/example/[slug].js → '/blog/:slug' ( ⇒ '/blog/hello-world')
pages/[username]/settings.js → '/:username/settings'(⇒ '/sook/settings')
pages/post/[...all].js → '/post/*' (⇒ '/post/2021/id/title')
 

기본 사용형태

Link 태그의 href 속성에 하위 경로를 작성.
보통 파라미터가 deep 하게 요구되지 않는 정적라우팅, (header 의 nav 이동같은 경우) Link 사용.
import Link from 'next/link' function Home() { return ( <ul> <li> <Link href="/"> <a>Home</a> </Link> </li> <li> <Link href="/about"> <a>About Us</a> </Link> </li> <li> <Link href="/blog/hello-world"> <a>Blog Post</a> </Link> </li> <li key={post.id}> <Link href={`/blog/${encodeURIComponent(post.slug)}`}> <a>{post.title}</a> </Link> </li> </ul>) } export default Home
또는 pathname , query 파라미터로 url 작성 가능
import Link from 'next/link' function Posts({ posts }) { return ( <ul> {posts.map((post) => ( <li key={post.id}> <Link href={{ pathname: '/blog/[slug]', query: { slug: post.slug }, }}> <a>{post.title}</a> </Link> </li>))} </ul>) }export default Posts
 

useRouter

react 컴포넌트에서 useRouter 훅(withRouter 도 사용가능하나 일반적으로 useRouter 사용) 을 대신하여 쓸 수 있다.
보통 파라미터에 의해 경로가 결정되는 경우 사용.
router.push는 외부 URL 사용시 사용할 필요 없다. window.location 에서 사용하는게 적합.

router object 로 쓸수 있는 method

router.push()에 각 형태에 맞게 router object 가 온다.
  • pathname : string 타입. 현재의 라우터가 온다. basePath || locale 은 포함되지 않음
  • query : object 타입. 만약 데이터 페칭이 요구되지 않는다면 pre-rendering 되는 동안은 빈 객체가 되기 때문에 {} 형태로 디폴트 값을 준다.
import { useRouter } from 'next/router' export default function ReadMore({ post }) { const router = useRouter() return ( <button type="button" onClick={() => { router.push({ pathname: '/post/[pid]', query: { pid: post.id }, }) }} > Click here to read more </button>) }
 
  • 그 외, router.replace 는 router.push 와 사용 용도, 사용법이 비슷하나,
router.replace 에서 새 URL 이 history stack 에 쌓이는 것을 방지할수 있는 기능이다.
  • router.reload = window.location.reload()

Shallow Routing

getServerSideProps, getStaticProps, getInitialProps(데이터fetching 세가지를 모두 합쳐놓은것.) 을 사용할 필요없이 useEffect 안에서 사용이 가능한 형태.
useRouter 에 의해 추가된 라우터 오브젝트, 기본세팅은 {shallow : true} .
즉 router.push() 에서 사용되어 업데이트된 pathname과 query 를 받을 수 있다.
import { useEffect } from 'react' import { useRouter } from 'next/router' // Current URL is '/' function Page() { const router = useRouter() useEffect(() => { // 첫번째 렌더 후 작동. router.push('/?counter=10', undefined, { shallow: true }) }, []) useEffect(() => { // 그 이후 카운터 변경. }, [router.query.counter]) } export default Page
해당 예시에서 쓰인 파라미터 counter = 10 는 페이지는 대체되지 않으나 라우트는 변경된다.