Next.js

Next.js : Routing

고래고래00 2024. 7. 2. 08:36

01. 설치

터미널
npx create-next-app@latest

 

02. 용어

Tree

  • Tree
    계층 구조를 시각적으로 잘 보기 위한 규칙(위 → 아래). DOM tree와 비슷
  • Subtree
    tree의 한 부분
    root부터 시작해서 leaf들에 이르기까지의 범위
  • Root
    Tree 또는 Subtree의 첫 번째 노드
  • Leaf
    children이 더이상 없는 node

URL

  • URL Segment
    슬래시(/)로 분류된 URL path의 한 부분
  • URL Path
    도메인(www.sample-web.com) 이후 따라오는 전체 URL 부분

03. 파일(폴더) 기반 라우팅

page.tsx

  • main ui가 표시될 곳
  • 폴더(nesting folders)를 만들어가면서 우리는 routing이 자동 구현
  • 이 과정에서 해당 폴더의 page.tsx 파일이 읽혀지게 됨

static routing

// src>app>test>page.tsx
import React from "react";

const TestPage = () => {
  return (
    <div>
      <h1>Test Page</h1>
      <p>안녕하세요! 테스트 페이지입니다</p>
    </div>
  );
};

export default TestPage;

dynamic routing

  • 폴더 이름을 대괄호로 설정

app/posts/[id]/page.tsx

// app>test>[id]>page.tsx
import React from "react";

const TestDetailPage = ({
  params,
}: {
  params: {
    id: string;
  };
}) => {
  return <div>Detail 페이지 : {params.id}</div>;
};

export default TestDetailPage;

route groups

  • 폴더명을 소괄호로 묶으면 routing에 포함되지 않음
// src>app>(admin)>about>page.tsx
import React from "react";

const AdminAboutPage = () => {
  return <div>소개 페이지입니다.</div>;
};

export default AdminAboutPage;

 

04. special files

특정 처리를 위해 생성

특정 처리의 예

  • 특정 경로 하위에 있는 routing은 모두 공통 layout을 적용
  • 특정 컴포넌트가 로딩중일 때, 오류가 발생했을 때 보여주고 싶은 UI

layout

  • 어떤 segment와 그의 자식 node에 있는 요소들이 공통적으로 적용받게 할 UI를 정의
  • 자식 node에 있는 요소들이 공통 적용을 받아야 하기 때문에 반드시 children prop이 존재해야 함
  • 동일 layout 안에서 다른 경로를 계속해서 왔다갔다 할 때 re-rendering이 일어나지 않음
    => headers, footers, sidebars 처럼 유저가 경로를 마음껏 탐색하고 다녀도 굳이 바뀔 필요가 없는 경우 유용

template

  • layout과 상당히 유사한 컴포넌트
  • 상태를 유지하는가? 리-렌더링이 일어나는가?
  • 경로 전반에 걸쳐서 상태가 유지되는 레이아웃과 달리,
    템플릿은 라우팅을 탐색할 때 각 하위 항목에 대해 새 인스턴스 생성
  • 즉, User 입장에서 동일한 Template을 공유하는 경로 사이를 왔다갔다 할 때 DOM 요소가 다시 생성된다는 것을 의미

use-case

1. 템플릿을 통한 페이지 open animation

  • 페이지 간 전환 시 애니메이션을 계속해서 주고 싶을 때
  • layout으로 만들어놓으면, 최초 렌더링시에만 animation이 적용되고 끝

2. useEffect, useState에 의존하는 기능

 

not-found

  • next.js에서는 별도 설정을 하지 않아도 기본 스타일이 된 not found 페이지를 제공

 

metadata와 SEO

  • Next.js는 기본적으로 Metadata를 가지고 있음
  • 향상된 SEO를 제공하기 위해서 기존 우리가 html head에 삽입했었던 많은 정보를 metadata는 객체 형태로 지원
  • Config-based Metadata를 활용

두 가지 버전 제시

1. static

원하는 page.tsx 또는 layout.tsx 에

export const metadata: Metadata = {
	title: "Sparta Next App",
	description: "This is awesome Website",
}

삽입만 하면 적용

  • metadata in page.tsx : 해당 page.tsx 컴포넌트에만 적용
  • metadata in layout.tsx : 해당 layout의 하위 요소에 모두 적용

2. dynamic

dynamic route를 갖고있는 route에서 동적으로 변경되는 params를 기반으로 metadata를 변경할 땐,
generateMetadata function을 사

import React from "react";

type Props = {
  params: {
    id: string;
  };
};

export function generateMetadata({ params }: Props) {
  return {
    title: `Detail 페이지 : ${params.id}`,
    description: `Detail 페이지 : ${params.id}`,
  };
}

const TestDetailPage = ({ params }: Props) => {
  return <div>Detail 페이지 : {params.id}</div>;
};

export default TestDetailPage;

05. 페이지 이동 관련 기능

Link

  • Next.js는 <Link>라는 리액트 컴포넌트를 제공
  • 기본 HTML의 <a> 태그를 확장한 개념

크게 두 가지 주요 역할

1. prefetching 지원

  • 뷰포트에 링크가 나타나는 순간 해당 페이지의 코드와 데이터를 미리 가져오는 프리페칭 기능 지원
  • 사용자가 링크를 클릭했을 때 거의 즉시 페이지를 볼 수 있음

2. route 사이에 client-side navigation 지원

  • 브라우저가 새 페이지를 로드하기 위해 서버에 요청을 보내는 대신, 클라이언트 측에서 페이지를 바꾸어 주기 때문에 페이지 전환 시 매우 빠른 사용자 경험(UX)을 제공
  • 페이지의 HTML을 서버에서 다시 가져올 필요 없이, 필요한 JSON 데이터만 서버로부터 가져와서 클라이언트에서 페이지를 재구성하여 렌더링

useRouter

더보기

useRouter를 사용할 때는 항상 코드 최상단에 “use client”를 삽입해야 함

  • a 태그를 알아차릴 수 없기 때문에 크롤러 입장에서는 해당 요소가 ‘이동을 원한다’라는 것을 알 수 없음 ⇒ SEO 불리
  • 대부분 onClick 같은 이벤트 핸들러에서 사용
  • 클릭 후 로직의 순서에 따라 실행하므로, 즉시 이동이 아님

router.push, router.replace, router.back, router.reload


router.push

  • 새로운 URL을 히스토리 스택에 추가합니다.
  • 사용자가 router.push로 페이지를 이동하면, 이동한 페이지의 URL이 히스토리 스택의 맨 위에 쌓임
  • 이후 사용자가 브라우저의 '뒤로 가기' 버튼을 클릭하면, 스택에서 가장 최근에 추가된 URL로부터 이전 페이지(URL)로 돌아감

router.replace

  • 현재 URL을 히스토리 스택에서 새로운 URL로 대체
  • 현재 페이지의 URL이 새로운 URL로 교체되며, '뒤로 가기'를 클릭했을 때 이전 페이지로 이동하지만, 교체된 페이지로는 돌아갈 수 없음
  • 현재 페이지를 히스토리에서 완전히 대체

router.back

  • 사용자를 히스토리 스택에서 한 단계 뒤로 이동
  • 마치 브라우저의 '뒤로 가기' 버튼을 클릭한 것과 같은 효과를 내며, 사용자를 이전에 방문했던 페이지로 돌아가게 함

router.reload

  • 현재 페이지를 새로고침
  • 히스토리 스택에 영향을 미치지 않음. 페이지의 데이터를 최신 상태로 업데이트하고 싶을 때 사용

 

a vs Link vs Router

a태그

  • 순수 HTML 요소
  • 완전한 새 페이지로 전환을 원할 때 : 페이지는 완전히 새로고침 됨
  • 빈 화면 보일 수 있음 ⇒ UX 좋지 않음

Link 태그

  • Link 태그는 a 태그를 만들어내기 때문에 SEO가 유리
  • 클릭 즉시 페이지 이동

Router(useRouter)

위 내용과 동일