[Next] 라우팅 시스템 (Next12)

Zero·2023년 10월 21일
0

[Next]

목록 보기
2/7
post-thumbnail

Route System

해당 글은 Next 13 이전 버전을 기준으로 작성하였습니다.

Next.js는 파일 시스템 기반의 라우터를 사용합니다.

  • 폴더(Folders)는 라우트를 정의하는데 사용됩니다.
  • 파일(Files)은 라우트 세그먼트에 대해 표시될 UI를 생성하는데 사용됩니다.

Next.js 프로젝트는 기본적으로 pages/ 디렉토리를 가지고 있습니다. 이 디렉토리 안의 모든 파일은 곧 페이지와 라우팅 규칙을 뜻합니다. 따라서 페이지 라는 것은 pages/ 디렉토리 안의 .js, .jsx, .ts, .tsx 에서 export한 리액트 컴포넌트라고 알 수 있습니다.

Next.js 프로젝트 구조

Next.js는 파일과 폴더명으로 라우터가 분리가되고 인식을 하기때문에 다음과 같은 규칙들이 준수되어야 합니다.

pages 라우팅 규칙

특별한 파일
_app: .js .jsx .tsx 커스텀 앱
_document: .js .jsx .tsx 커스텀 문서
_error: .js .jsx .tsx 커스텀 오류 페이지
404: .js .jsx .tsx 404 오류 페이지
500: .js .jsx .tsx 500 오류 페이지

라우트 규칙

폴더 규칙
index: .js .jsx .tsx 홈페이지
folder/index: .js .jsx .tsx 중첩된 페이지

파일 규칙
index: .js .jsx .tsx 홈페이지
file: .js .jsx .tsx 중첩된 페이지

동적 라우트

폴더 규칙
[folder]/index: .js .jsx .tsx 동적 라우트 세그먼트
[...folder]/index: .js .jsx .tsx 모든 세그먼트 포착
[[...folder]]/index: .js .jsx .tsx 선택적 모든 세그먼트 포착

파일 규칙
[file]: .js .jsx .tsx 동적 라우트 세그먼트
[...file]: .js .jsx .tsx 모든 세그먼트 포착
[[...file]]: .js .jsx .tsx 선택적 모든 세그먼트 포착

url을 통해서 페이지에 접근하는 방법


세그먼트

pages/ 내의 각 폴더는 라우트 세그먼트를 나타냅니다. 각 라우트 세그먼트는 URL 경로의 해당 세그먼트에 매핑됩니다.

예시 폴더구조는 다음과 같습니다.
폴더구조

접근하는 방법은 각각 다음 주소로 접근합니다.

/  // root 경로
/main  // mainPage
/post  // postPage
/post/[postid]  // postDetailPage

루트를 제외한 나머지 같은 경우 폴더 이름이 세그먼트가 된 것을 확인 할 수 있습니다.


페이지에서 동적 매개변수를 사용하는 방법


postDetailPage 같은 경우 동적 매개변수를 가져오기 때문에 postPage에서 추가 경로가 필요합니다.
export type PostDetailPropsType = {
    postId: string
}
export async function getServerSideProps({params}: { params: PostDetailPropsType }) {
    const {postId} = params;
    return {
        props: {
            postId
        }
    }
}
const PostDetailPage = (props: PostDetailPropsType) => (
    <>This is PostPage :( {props.postId}</>
);
export default PostDetailPage;

컴포넌트에서 동적 매개변수를 사용하는 방법


페이지와 달리 컴포넌트는 파람으로 가져올 수 없습니다. 그 이유는 페이지 밖에서 getServerSideProps 혹은 getStaticProps를 사용할 수 없기 때문입니다. 그러면 무조건 props로 넘겨주는 방법밖에 없을까요? 정답은 useRouter 훅을 사용하면 됩니다.

import { useRouter } from "next/router";

const PostTitle = () => {
    const { query } = useRouter()
    return <header>{query.postId} 게시물에 관한 정보입니다.</header>
};

export default PostTitle;

useRouter는 동적 매개변수 이외에도 param값 들도 받아올 수 있습니다.

다음 주소로 url을 입력을 합니다. http://localhost:3000/post/32?name=brian22&age=22
그러면 다음과 같은 결과를 위에 query를 출력함으로서 받아올 수 있습니다.

{
  age : "\"20\"",
  name : "\"brian\"",
  postId : "32"
}

클라이언트에서의 내비게이션


리액트 웹 애플리케이션을 서버에서 렌더링을 하려고 만든 프레임 워크가 아닙니다. 다양한 기능을 비롯하여 성능을 최적화할 수 있느 많은 방법을 제공합니다. 그 중 하나가 바로 클라이언트에서 내비게이션을 처리하게하는 것입니다.

기존 html<a> 태그를 이용하여 페이지를 연결할 수도 있지만 <Link> 컴포넌트를 통해 서로 다른 라우트 간의 이동을 최적화 할 수 있습니다.
Next.js는 현재 화면에 표시되는 모든 Link에 대해 연결된 부분 또는 페이지를 미리 불러올 수 있습니다. 만약 미리 불러오는 기능을 끄고싶다면 Link 컴포넌트에 preload={false} 속성을 주면 됩니다.

const Layout = () => (
<header>
    <nav style={{display: 'flex', gap: '5px'}}>
        <Link href={'/main'}>Main</Link>
        <Link href={'/post'}>Post</Link>
        <Link href={'/post/13'}>Post</Link>
        <Link href={'/post/[postId]'} as={'/post/13'}>Post</Link>
        <Link href={{pathname: '/post/[postId]', query: {postId: 13}}}>Post</Link>
    </nav>
</header>
)

코드 아래 3개의 포스트 상세페이지로 가는 <Link>는 사용법은 다르지만 모두 한 경로를 나타내고 있습니다. 이처럼 복잡한 URL을 사용한다면 href에 속성에 객체를 전달할 수도 있습니다.

router.push

useRouter 훅에서 제공하는 push() 메소드도 사용할 수 있습니다.

const navigate = useRouter();

const onClick = async () => {
    await navigate.push('/post/32')
}

...

const Layout = () => (
<header>
	<nav style={{display: 'flex', gap: '5px'}}>
    	<Link href={'/main'}>Main</Link>
		<Link href={'/post'}>Post</Link>
		<button onClick={onClick}>PostDetail</button>
	</nav>
</header>
)

페이지 연결시 주의사항

  1. 서버 컴포넌트 는 서버/클라이언트를 모두 불러 사용할 수 있지만, 클라이언트 컴포넌트는 클라이언트 컴포넌트만 가져다 사용할 수 있습니다.

  2. 서버 컴포넌트에서 클라이언트 컴포넌트로 전달되는 props는 직렬화 가능해야 합니다. 함수, 날짜 같은 것들은 전달할 수 없습니다.

profile
0에서 시작해, 나만의 길을 만들어가는 개발자.

0개의 댓글