Next.js - 페이지별 레이아웃 설정하기

윤스타·2024년 10월 6일

Next.js

목록 보기
7/9
post-thumbnail

페이지별 레이아웃 설정하기

(Page Router 기준)

<SearchableLayout>컴포넌트를 특정 페이지에만 적용시키고 싶지만 아래와 같이 적용한다면 모든 페이지에 적용이 될 것이다.

// app.tsx
import GlobalLayout from "@/components/global-layout";
import SearchableLayout from "@/components/searchable-layout";
import "@/styles/globals.css";
import type { AppProps } from "next/app";

export default function App({ Component, pageProps }: AppProps) {
  return (
    <GlobalLayout>
      <SearchableLayout>
        <Component {...pageProps} />
      </SearchableLayout>
    </GlobalLayout>
  );
}

따라서 다른 방식을 찾아야 하는데, 아래와 같이 하는 것이다.

레이아웃을 적용시키고 싶은 컴포넌트에서 getLayout메서드를 통해 propspage를 넘겨준 뒤, return문을 <SearchableLayout>컴포넌트로 감싼 상태로 작성한다.

// index.tsx
import SearchableLayout from "@/components/searchable-layout";
import { ReactNode } from "react";

export default function Home() {
  return <h1 className={style.h1}>메인 페이지</h1>;
}

Home.getLayout = (page: ReactNode) => {
  return <SearchableLayout>{page}</SearchableLayout>;
};

그리고 App.tsx파일에서 props로 넘겨받은 ComponentgetLayout메서드를 이용하여 getLayout을 정의해준 뒤, 아래와 같이 getLayout의 인자로 <Component {...pageProps} />를 전달해준다

// app.tsx
import GlobalLayout from "@/components/global-layout";
import "@/styles/globals.css";
import type { AppProps } from "next/app";

export default function App({ Component, pageProps }: AppProps) {
  const getLayout = Component.getLayout;

  return <GlobalLayout>{getLayout(<Component {...pageProps} />)}</GlobalLayout>;
}

그치만 그냥 이렇게 작성하고 마무리를 할 경우, getLayout메서드를 사용하지 않은 페이지를 렌더링 하려고 할 때, getLayoutundefined가 되는 상황이 발생하여 에러가 발생할 수 있다.

따라서 예외 처리를 반드시 해줘야 한다.

??연산자를 사용하여 Component.getLayoutundefined가 되는 경우, 그냥 ((page: ReactNode) => page)를 리턴하도록

또한 getLayout에 대한 타입도 지정해야 한다.

// app.tsx
import GlobalLayout from "@/components/global-layout";
import "@/styles/globals.css";
import { NextPage } from "next";
import type { AppProps } from "next/app";
import { ReactNode } from "react";

type NextPageWithLayout = NextPage & {
  getLayout?: (page: ReactNode) => ReactNode;
};

export default function App({
  Component,
  pageProps,
}: AppProps & { Component: NextPageWithLayout }) {
  const getLayout = Component.getLayout ?? ((page: ReactNode) => page);

  return <GlobalLayout>{getLayout(<Component {...pageProps} />)}</GlobalLayout>;
}
profile
사이버 노트

0개의 댓글