본격적인 Nextjs 개발을 시작하기 전 Next.js 13에서 추가된 내용들에 대해 정리해보려고 한다.👻
Next.js 13에서는 앱 라우터는 app
이라는 새 디렉터리에서 작동한다.
기존에는 페이지 라우팅을 pages 디렉터리로 처리했었어서, 이 점이 가장 큰 변경점으로 다가왔다.
layout은 여러 페이지들에서 사용하고 공유되는 UI를 정의하는 것을 목적으로 한다.
이를 통해 공통 레이아웃의 상태를 유지하고, 불필요한 리렌더링을 방지할 수 있다고 한다.
// app/page.tsx
export default function Home() {
return (
<>
<h2>Hello World</h2>
</>
);
}
// app/layout.tsx
export default function RootLayout({
children,
}: {
children: React.ReactNode;
}) {
return (
<html>
<body>
{children}
<ul>
<li>
<a href="/create">create</a>
</li>
<li>
<a href="/update/id">update</a>
</li>
</ul>
</body>
</html>
);
}
이와 같이 app 디렉터리 밑에 page.tsx와 layout.tsx를 수정해보면
layout.tsx의 내용이 공유되는 것을 확인해볼 수 있다.
참고)
만약 위의 이미지처럼 두 레이아웃을 결합하는 경우, 루트 레이아웃(app/layout.js)은 대시보드 레이아웃(app/dashboard/layout.js)을 래핑하게 된다.
app
디렉터리에선 디폴트로 서버 컴포넌트가 적용된다. 이를 통해 추가 구성 없이 서버 렌더링을 자동으로 구현할 수 있으며, 서버 컴포넌트는 클라이언트에 전송되는 javascript 코드량을 줄여서 초기 페이지 로드 속도를 높일 수 있다.
만약 서버가 아닌 클라이언트 컴포넌트를 생성하고 싶다면 파일 상단에 use client
라는 directive를 명시해줘야 한다.
"use client";
import { useState } from "react";
export default function Counter() {
const [count, setCount] = useState(0);
return (
<div>
<p>You clicked the Count++ button {count} times</p>
<button onClick={() => setCount(count + 1)}>Count++</button>
</div>
);
}
서버 컴포넌트를 사용해야 할 때와 클라이언트 컴포넌트를 사용해야 할 때는 다음과 같다.
한가지 유의해야 할 점은 클라이언트 컴포넌트에 서버 컴포넌트를 가져오는 패턴은 지원되지 않는 패턴이라는 것이다.
'use client'
// Server Component를 Client Component에 import할 수 없다 !
import ServerComponent from './Server-Component'
export default function ClientComponent({
children,
}: {
children: React.ReactNode
}) {
const [count, setCount] = useState(0)
return (
<>
<button onClick={() => setCount(count + 1)}>{count}</button>
<ServerComponent />
</>
)
}
대신, 서버 컴포넌트를 클라이언트 컴포넌트에 props으로 전달할 수 있다.
'use client'
import { useState } from 'react'
export default function ClientComponent({
children,
}: {
children: React.ReactNode
}) {
const [count, setCount] = useState(0)
return (
<>
<button onClick={() => setCount(count + 1)}>{count}</button>
{children}
</>
)
}