Next.js 튜토리얼 (2) - 뼈대부터 라우팅까지

sham·2024년 11월 19일

Next.js 제로베이스

목록 보기
2/9
post-thumbnail

뼈대 만들기

각 디렉토리의 page.js라는 파일이 해당 디렉토리의 이름으로 매핑되는 파일이 된다.

React의 index.jsx와 유사하다고 생각하면 될 것이다.

src/app/page.js

import Image from "next/image";

export default function Home() {
  return (
    <div className="grid grid-rows-[20px_1fr_20px] items-center justify-items-center min-h-screen p-8 pb-20 gap-16 sm:p-20 font-[family-name:var(--font-geist-sans)]">
      Hello, Nextjs!
    </div>
  );
}

src/app/layout.js

import './globals.css'
export const metadata = {
  title: 'WEB tutorial',
  description: 'Generated by egoing',
}
export default function RootLayout({ children }) {
  return (
    <html>
      <body>
        <h1><a href="/">WEB</a></h1>
        <ol>
          <li><a href="/read/1">html</a></li>
          <li><a href="/read/2">css</a></li>
        </ol>
        {children}
        <ul>
          <li><a href="/create">create</a></li>
          <li><a href="/update/id">update</a></li>
          <li><button>delete</button></li>
        </ul>
      </body>
    </html>
  )
}

Route

page.js, layout.js, not-found.js 같은 특정 예약된 파일의 경우, 파일 이름이 중요하지 코드 상 컴포넌트의 이름은 뭐가 되었든 동작에 영향을 주지 않는다. (심지어 대문자가 아니어도 된다!)

기본 구조 (page.js, layout.js)

  • app 디렉토리 안의 파일이라면 자동으로 컴포넌트의 이름에 맞게 URL이 매핑된다. 이 때, export default된 react 컴포넌트여야 한다.
  • page.js, layout.js 같은 특정 예약된 파일이름은 다른 방식으로 동작한다.
    • page.js : 각 디렉토리 마다 하나씩만 존재할 수 있으며, 해당 폴더의 경로가 URL 경로로 매핑된다.
    • layout.js : 특정 경로와 하위 경로에 적용될 레이아웃을 ****정의한다.
      • 만약 개발 서버가 돌아가는 도중에 layout.js가 삭제된다면 next는 자동으로 layout.js를 생성시킨다.

not-found.js

  • 404 페이지에 해당한다. 존재하지 않는 URL로 이동할 경우 해당 컴포넌트로 리다이렉팅된다.

error.js

  • 500 에러에 해당한다. throw 등의 에러가 감지되었을 때, 해당 컴포넌트로 리다이렉팅된다.

Route Group (괄호)

  • route를 그룹화하여서 논리적인 그룹으로 형성한다. 파일 구조를 관리하는데 주로 사용된다.
  • Route Group은 특정 그룹 내 경로에만 적용되는 layout.js 파일을 정의할 수 있다.
    • 같은 URL 구조를 공유하면서도 다른 레이아웃을 적용시키는 것이 가능하다.
  • 괄호로 명명된 폴더는 url에 어떠한 영향도 주지 않는다.
app/
├── (marketing)/
│   ├── about/
│   │   └── page.js
│   └── contact/
│       └── page.js
├── (dashboard)/
│   ├── settings/
│   │   └── page.js
│   └── profile/
│       └── page.js
└── page.js
  • app/(marketing)/about/page.js의 경로는 /about으로 매핑된다.
  • app/(dashboard)/settings/page.js의 경로는 /settings으로 매핑된다.

Dynamic Route ([])

경로가 고정되지 않고, URL에 따라 변할 수 있는 경로를 설정할 수 있는 기능이다.

대괄호([])를 사용하여 파일이나 폴더 이름을 정의함으로써 생성된다.

예를 들어, app/[id]/page.js/123, /product, /my-page와 같은 동적인 URL을 처리할 수 있다.

params에는 대괄호 안에 적은 폴더의 이름을 키 값으로 하는 해당 url의 값이, searchParams에는 ? 형태로 들어온 쿼리 문이 객체로 들어온다.

Next.js의 App Router에서 데이터를 비동기로 처리하게끔 하기에 paramssearchParamsPromise 객체로 만들어진다. await 등으로 Promise Pending 상태를 해제해주자.

export default async function Movie(props) {
  const resolvedParams = await props.params; // Promise 해제
  const resolvedSearchParams = await props.searchParams;

  console.log("params:", resolvedParams);
  console.log("searchParams:", resolvedSearchParams);
  return (<div className="">Movie! Movie! </div>);
}

Navigation

  • 브라우저 상의 <a href=””>를 사용하지 않고, next 프레임워크가 제공하는 Link를 사용할 수 있다.
import Link from "next/link";

export default function Navigation() {
  return (
    <nav>
      <Link href="/">Home</Link>
      <Link href="/test">Test</Link>
      <Link href="/error">Error </Link>
    </nav>
  );
}

usePathname

  • 현재 url의 경로를 리턴해준다.
  • client component에서만 동작한다.
"use client";

import Navigation from "@/components/navigation";
import { usePathname } from "next/navigation";

export default function HoGGGme() {
  const path = usePathname();

  return (
    <div className="grid grid-rows-[20px_1fr_20px] items-center justify-items-center min-h-screen p-8 pb-20 gap-16 sm:p-20 font-[family-name:var(--font-geist-sans)]">
      <Navigation />
      Hello, Nextjs!
      <div>cur path : {path}</div>
    </div>
  );
}

layout

페이지 틀을 담당하는 상위 컴포넌트이다.

중첩이 가능하기에 용도에 따라 다르게 중첩된 컴포넌트를 만들 수 있다.

metadata는 서버에서만 작동하는 API이기에 use client와 동시에 사용할 수 없다. layout 컴포넌트에서 클라이언트 컴포넌트가 필요하다면, 자식 컴포넌트로 가지는 방법을 사용하는 것이 바람직하다.

import Navigation from "@/components/navigation";
import PathDisplay from "@/components/pathdisplay";

export const metadata = {
  title: "Next.js",
  description: "Generated by Next.js",
};

export default function RootLayout({ children }) {
  return (
    <html lang="en">
      <body>
        <Navigation />
        <PathDisplay />
        {children}
      </body>
    </html>
  );
}

Metadata

layout.js 혹은 page.js에서 metadata를 export하면 html의 head 안에 내용을 생성할 수 있다.

이 때 반드시 해당 컴포넌트는 서버 컴포넌트여야만 한다. (use client와 함께 쓸 수 없다.)

상위의 Metadata를 찾는 과정에서 하나의 Metadata를 여러 페이지(컴포넌트)가 공유하게 될 수 있다.

여러 개의 Metadata가 존재한다면 병합되며, 중복되는 속성의 경우 해당 url에서 가장 가까운 속성 값을 사용한다.

TS라면 템플릿을 사용해 동적인 값을 넣어줄 수 있다.

export const metadata: Metadata = {
  title: {
    template : "%s | Next.js",
    default: "Loading...",
  }
  description: "Generated by Next.js",
};
profile
씨앗 개발자

0개의 댓글