Next.js v13이 나온지 벌써 반년이 지났네요.
v13의 기능인 app routing에 적응하고 잘 사용할 수 있는 개발자도 있겠지만
아직 적응하지 못 하고 낯선 개발자도 있다고 생각합니다.
이번 글에서는 크게 page routing과 app routing의 구조 특징들을 알아보겠습니다.
( app routing의 모든 기능을 설명하는 건 다른 포스트에서 작성하도록 하겠습니다! )
Page Routing
Next.js에서는 파일 기반 라우팅을 제공합니다. 얼마나 유용하냐면
React.js에서는 react-router-dom을 설치하고 Route로 하나하나 경로를 설정하고 해당하는 컴포넌트를 작성하는데
반면 Next.js는 page 폴더 안에서 파일의 이름만으로 라우팅을 자동으로 구성해줍니다!
page 폴더 안에서 club.tsx라는 파일을 생성했다면 /club 경로에선 club.tsx가 보여지는 형식입니다.
page 폴더를 기준으로 파일 기반 라우팅을 제공하는 것은 충분히 설명한 것 같습니다.
이런 page 폴더는 기본으로 2가지 파일이 존재하는데 그 중의 _documents.tsx는 사용자가 직접
생성할 수 있습니다.
index.tsx
index.tsx는 기본 경로라고 생각하시면 됩니다.
예시로 다음과 같은 경로를 설정하고 싶다면
/club
/club/users
아래와 같이 라우팅을 nesting 할 수 있습니다.
폴더를 만들고 그 폴더안의 index 파일을 만들면 폴더의 이름이 경로가되어
해당 경로에서 index.tsx 파일의 내용이 보여집니다. 이러면 중첩 라우팅 어렵지 않겠죠?
물론 폴더를 만들지 않고 파일의 이름만으로도 경로가 생성됩니다.
user.tsx -> /user
_app.tsx
_app.tsx 사실 언더바가 붙은 파일은 생소합니다. 그래서 어색할 수 있지만 어렵지 않습니다.
간단히 말해 Next.js에서 최상위라고 생각하면 됩니다. 프로젝트의 모든 컴포넌트가
_app.tsx 파일 하위에서 렌더링 되는거죠.
_app.tsx 파일은 기본적으로 아래와 같이 구성되어 있습니다.
import '../styles/globals.css'
import type { AppProps } from 'next/app'
function MyApp({ Component, pageProps }: AppProps) {
return <Component {...pageProps} />
}
export default MyApp
컴포넌트의 이름은 MyApp이든 무슨 이름이든 상관없습니다. _app.tsx가 최상위라고 말했죠? 그래서 모든 컴포넌트에 공통 스타일을
적용시키고 싶다면 _app.tsx 파일에 적용해주면 됩니다. React로 치자면 index.tsx라고 생각하면 쉽게 이해될 것 같네요.
스타일 뿐만 아니라 Redux, Recoil, Theme 등등 특정 라이브러리들은 최상위 컴포넌트에서 Provider를 감싸줄 필요가 있습니다.
이런 Provider들을 _app.tsx에서 작성하면 됩니다.
props로 Component, pageProps를 받습니다. 간단합니다. 어떤 경로에 접속했을 때 page 폴더안에서 경로를 찾아
해당하는 파일의 컴포넌트가 바로 Component입니다.
만약 /club 으로 이동했다면 pages/club/index.tsx 의 컴포넌트가 Component가 되는것입니다.
그럼 pageProps는 뭔지 예상되시나요? 말 그대로 Component의 props들입니다. 스프레드 연산자로
Component의 모든 props를 내려줍니다.
_documents.tsx
_app.tsx와 똑같이 언더바가 붙어있는 파일이네요. _app.tsx와 같이 특별한 기능을 수행하는 파일이라고 생각할 수 있습니다.
Next.js는 SSR을 제공합니다. _documents.tsx 파일은 서버 사이드 렌더링 시에 기본적은 HTML문서의 구조를 정의하는 파일입니다.
HTML 구조이기 때문에 html, head, meta, body 등등을 세팅할 수 있습니다. 처음 install할 때 파일이 없는 이유는 Next.js가 자체적으로 document 파일을 제공하기 때문입니다. 하지만 특정 구조를 더하고 싶다면 생성해야겠죠? ex) meta
import { Html, Head, Main, NextScript } from 'next/document'
export default function Document() {
return (
<Html lang='ko'>
<Head />
<body>
<Main />
<div id='modal' />
<NextScript />
</body>
</Html>
)
}
제 프로젝트에서 사용하던 _documents.tsx 파일입니다.
App Routing
Page Routing의 특징에 대해 알아보았습니다.
이제 구조가 많이 개편됐던 App Routing에 대해 알아보겠습니다.
App Routing은 Next.js v13 이상부터 사용할 수 있습니다. page routing은 page 폴더를 기반으로 했습니다.
당연히 app routing은 app 폴더를 기반으로 파일 기반 라우팅을 제공합니다.
page
대신 index.tsx가 아니고 무조건 page.tsx라는 이름으로 작성해야 라우팅이 구성됩니다.
즉, 위처럼 /club/users를 하고 싶다면 index.tsx를 page.tsx로 이름을 바꾸어야 합니다. page.tsx 이외의 파일은
그저 일반 컴포넌트로 구분됩니다. 그래서 단일 경로도 무조건 폴더를 만들고 page.tsx로 구성해야 합니다.
위처럼 page.tsx가 아닌 info.tsx는 일반 컴포넌트입니다. club/users/info로 url을 작성하면 404를 반환합니다.
info는 더 이상 경로가 아니라 그저 컴포넌트니까요.
app에서 page.tsx 파일이 있다면 처음 보여지는 페이지겠죠?
layout.tsx
새로운 파일이 보이시나요? layout.tsx가 새로 나타났습니다.
layout.tsx는 page routing의 _app.tsx와 마찬가지로 최상위에서 감싸는 역할을 합니다.
다만 root 디렉토리에 있어야만 하는 것이 아니라 각각의 페이지를 위한 폴더에도 생성할 수 있다는 차이가 있습니다.
root layout
import type { Metadata } from "next";
import { Inter } from "next/font/google";
import "./globals.css";
const inter = Inter({ subsets: ["latin"] });
export const metadata: Metadata = {
title: "Create Next App",
description: "Generated by create next app",
};
export default function RootLayout({
children,
}: Readonly<{
children: React.ReactNode;
}>) {
return (
<html lang="en">
<body className={inter.className}>{children}</body>
</html>
);
}
app/layout.tsx의 초기 모습입니다. metadata라는 객체가 생겨났죠?
이 metadata 객체로 검색엔진최적화를 할 수 있습니다. export 해주면 자동으로 meta 태그가 추가됩니다.
SEO 최적화를 위한만큼 title, description을 제외한 많은 기능을 제공합니다!
https://nextjs.org/docs/app/building-your-application/optimizing/metadata
Optimizing: Metadata | Next.js
Use the Metadata API to define metadata in any layout or page.
nextjs.org
layout은 페이지를 위한 폴더에서도 생성할 수 있다고 말했는데 layout만 포함되는 것은 아닙니다.
app routing은 각 페이지 폴더마다 각기 다른 구조를 지을 수 있는 것을 추구하는 것 같습니다!
한 페이지 폴더안의 많은 기능의 파일들이 들어가있습니다.
error, loading은 해당 페이지 컴포넌트에서 데이터 페칭시의 로딩, 오류 등이 나타났을 때 보여줄 UI를 정의합니다.
React의 Suspense를 이용하네요.
물론 아래처럼 nesting 해줄 수도 있습니다!
page routing보다 훨씬 구조적인 형태를 띄고 있는 것을 확인할 수 있습니다.
각 페이지 폴더마다 다른 UI 및 구조를 가질 수 있는 것도 매력적인 것 같네요.
RSC ( React Server Component ), RCC ( React Client Component )
app routing에서 가장 큰 핵심이라고 할 수 있는 개념이 남았습니다.
바로 React Server Component와 React Client Component를 구분할 수 있는 것입니다.
Client Component는 흔히 우리가 사용하는 리액트 컴포넌트라고 생각하시면 됩니다.
좀 더 자세히 설명해보겠습니다. js 관련 코드가 있냐 없냐가 Server Component와 Client Component를 나눕니다.
Hydration이 이루어지느냐로 나눌 수 있다는 것이죠.
Hydration은 Server Side에서 렌더링 된 정적 페이지인 HTML과 번들링 된 JS 파일을 보내면
Client Side에서 HTML 코드와 JS 코드를 서로 매칭시키는 과정입니다.
( Hydration은 수분 공급이라는 의미를 가지고 있습니다. 매마른 정적 페이지에 js가 흘러들어오는! )
Server Component는 Hydration 과정을 겪지 않기 때문에 Client Component보다 빠르게
페이지를 렌더링 시킬 수 있다는 장점이 있습니다.
아 물론 Hydration은 Next.js만의 기능이 아닙니다. ReactDOM의 함수입니다.
Hydration도 따로 포스트로 정리해보겠습니다. :)
자! 그럼 Next.js는 어떻게 구분할까요? 바로 컴포넌트 맨 윗줄에
"use client"
를 적으면 Client Component 적지 않으면 Server Component로 Next.js가 인식합니다.
만약 상위와 하위 파일이 있을 때 상위 하위 둘 다 Client Component라면 둘 다 명시하지 말고
상위 파일에만 명시해주면 하위 파일에서 명시하지 않아도 됩니다.
Server Component에서 js 관련 코드를 작성했다면 Next.js는 use client를 명시하라고 에러를 띄웁니다.
📚 정리
구조만 설명하는데도 길이가 많네요..
page routing
- 최상위 _app, _documents 파일이 있음
- page 디렉토리를 기반으로 파일 기반 라우팅을 제공
- 파일의 이름자체가 경로가 됨
app routing
- 최상위 root layout이 필요함
- 파일을 위한 폴더 생성 후 page라는 이름이 아니면 경로로 취급되지 않음
- layout, error, loading 등의 파일에 따라 각 페이지마다 다른 UI를 가질 수 있음 ( 구분되어 있어 강력한 구조! )
- RSC, RCC 구분으로 페이지 렌더링 속도를 향상시킴
'Next.js' 카테고리의 다른 글
매마른 페이지에 수분 공급! - Hydration (0) | 2024.04.21 |
---|