(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메서드를 통해 props로 page를 넘겨준 뒤, 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로 넘겨받은 Component에 getLayout메서드를 이용하여 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메서드를 사용하지 않은 페이지를 렌더링 하려고 할 때, getLayout이 undefined가 되는 상황이 발생하여 에러가 발생할 수 있다.
따라서 예외 처리를 반드시 해줘야 한다.
??연산자를 사용하여 Component.getLayout가 undefined가 되는 경우, 그냥 ((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>;
}