layout은 페이지간에(routes) 공유가 가능한 UI이다. 그래서 layout.js파일은 여러 페이지(page.js)들에 공통적으로 적용되는 UI를 정의하는 컴포넌트라고 할 수 있다. layout.js는 하위의 page.js 및 layout.js 를 자식(children)으로 감싸서 화면을 렌더링 한다. 따라서 여러 레이아웃을 만들어 두고, 부모-자식 레이아웃 구조로 중첩하여 적용하는 방식도 가능하다.
이 layout파일은 어느 폴더든 만들고 싶은 곳에 만들 수 있고 폴더 안에 있는 자식 폴더에서도 공유가 가능하다.
또한 레이아웃(Layout)에 정의된 UI와 상태 값들은, (경로 이동-Navigation 등이 발생하더라도) 계속해서 유지되며 재렌더링 되지 않고 재활용된다.
보통 header,navbar,footer등 어느 페이지건 변하지 않고 공통적이고 고정적으로 들어가는 부분을 layout으로 만들어둔다.
Next프로젝트를 생성하면 기본적으로 app폴더 안에 layout파일이 생성되는데 이 파일이 루트 레이아웃이다. /app 디렉토리의 최상위에 있는 layout.js파일로, 모든 route경로에 적용이 된다. 이 말은 /app경로에 있는 폴더 그리고 그 폴더의 자식 폴더에 정의된 모든 page.js나 layout.js 컴포넌트들은 루트 레이아웃의 자식이 되어서 렌더링이 된다는 뜻이다.
루트 레이아웃은 app디렉토리의 최상위 레이아웃으로 html과 body태그를 반드시 포함해야 한다.
다른 중첩 폴더에 layout.js가 있더라도, 반드시 /app 최상위 레벨에 루트 layout.js 파일이 존재해야 한다.
필요에 따라 (Route Group)으로 구분하여 정의할 수도 있다.
<html>
과 <body>
태그를 포함해야 한다.오직 루트 레이아웃만 이 태그들을 포함할 수 있다.
다른 하위의 레이아웃은 이 태그들을 포함할 수 없다.
루트 레이아웃은 Client Component로 전환해선 안 된다.
루트 레이아웃을 제외한 하위의 다른 레이아웃들은 Client Component로 전환할 수 있다.
// layouts/MainLayout.js
const MainLayout = ({ children }) => {
return (
<div>
<header>Header</header>
<main>{children}</main>
<footer>Footer</footer>
</div>
);
};
export default MainLayout;
// pages/index.js
import MainLayout from '../layouts/MainLayout';
const HomePage = () => {
return (
<MainLayout>
<h1>Welcome to the Home Page</h1>
</MainLayout>
);
};
export default HomePage;
여기서 MainLayout컴포넌트의 "children" 프로퍼티는 h1태그의 Welcome to the Home Page가 된다. 따라서 레이아웃은 이 내용을 감싸고 다양한 페이지에 동일한 레이아웃을 적용할 수 있게 된다.
// app/shop/[tag]/[item]/layout.tsx
export default function ShopLayout({
children,
params,
}: {
children: React.ReactNode
params: {
tag: string
item: string
}
}) {
// URL -> /shop/shoes/nike-air-max-97
// `params` -> { tag: 'shoes', item: 'nike-air-max-97' }
return <section>{children}</section>
}
이를 통해 레이아웃 컴포넌트에서 동적 경로에서 추출한 파라미터 값을 활용할 수 있다.
알아두어야 할 내용으로 Layout 컴포넌트는 searchParams 프로퍼티를 받지 않는다는 것이다. 이는 페이지 간의 네비게이션에서 레이아웃 컴포넌트가 어떻게 동작하는지에 대해 알 수 있다.
이를 통해 결과적으로 공통된 레이아웃을 가진 페이지 간의 네비게이션이 더욱 효율적으로 처리되며, 레이아웃이 네비게이션 중에 다시 렌더링되지 않아도 되기 때문에 성능이 향상된다.
출처