라이브러리&프레임워크/Next.js

[Next.js] Layout, getLayout

youngble 2022. 11. 17. 15:51

Layouts

여러 page들의 공통 처리

 

하나의 공통된 layout을 쓰는 경우

Components/Layout.js

컴포넌트 하나를 pages/_app.js 에서 활용하면 됨

 

만약 여러개의 Layouts을 활용하고 싶은 경우

Components/SubLayout.js

Page.getLayout getLayout 함수를 제공

 

Next.js에서 다른 url path로 이동하거나 새로고침시에 전역적으로 사용하는 header, navigator 같은 형식이나, 전체적으로 가져가고싶은 css 등을 설정할수 있게하는 기능이 있다. 이를 전체 한개의 layout으로 쓸 Layout이라는 컴포넌트와 그외에 추가적인 layout을 쓴다면 SubLayout을 만들어서 사용한다.

 

먼저 Layout.js 컴포넌트를 보면 기존 리액트 propschildren로 사용하면 된다 이때 예제에서는 컴포넌트의 매개변수를 구조분해 할당 destructuring 으로 {children} 형식으로 쓰기때문에 그 방식대로 적용해본다. 

import Head from "next/head";

export default function Layout({ children }) {
  return (
    <div className="container">
      <Head>
        <title>Create Next App</title>
        <link rel="icon" href="/favicon.ico" />
      </Head>
      <main>{children}</main>
      <footer>
       <div>test footer</div>
      </footer>
    </div>)
 }

이렇게 기본 Layout 컴포넌트를 만들고 main 태그로 children을 감싸주었다.

 

그리고 제일 먼저 실행되는 _app.js를 만들고 그안에서 해당 layout을 설정해준다.

기본 셋팅 코드는 다음과 같다.

//모든페이지를 품을수 있는
import Layout from "../components/Layout";
export default function App({ Component, pageProps }) {
 return (
     <Layout>
       <Component {...pageProps} />
     </Layout>
 );
}

코드를 설명하면 App 컴포넌트안에서 두개의 인자 Component, pageProps를 return에서 사용하는데 먼저 Component는 해당 주소 url path에서 사용되는 컴포넌트 Component 를 나타내고, pagePropsgetStaticPropsgetServerSideProps 등 해당 GetInitialProps의 data들을 넘겨주는 것이다. 이때 <Layout>으로 감싸주기 때문에 위에 설정한 컴포넌트가 전역으로 사용된다는 것이다.

 

만약에 하나의 Layout이 아닌 여러개 혹은 sub로 추가로 레이아웃을 사용하고 싶다면 다음과 같이 쓴다.

import Link from "next/link";

export default function SubLayout({ children }) {
  return (
    <div>
      <h1>
        <Link href="/">Home 으로</Link>
      </h1>
      {children}
    </div>
  );
}

SubLayout을 만들고 Layout과 마찬가지로 {children}을 사용해준다. 그리고 _app.js로 가서 위에서 설정한거에서 조금 바꿔준다.

//모든페이지를 품을수 있는
import Layout from "../components/Layout";

export default function App({ Component, pageProps }) {
  const getLayout = Component.getLayout || ((page) => <Layout>{page}</Layout>);
  return getLayout(<Component {...pageProps} />);
}

getLayout이라는 변수에 Component.getLoayout이 있으면 그 함수를 담아주고 그게 아니라면 기존 <Layout>을 사용하도록 했다.

이때 getLayout이라는 함수 역시 next에서 제공하는 함수로 알고있다. 예를들어 내가 /csr 이라는 경로에서 사용하는 컴포넌트에 해당 layout, sublayout을 적용하고싶다면

다음과 작성하면 위에 App에 getLayout변수에 담기게 된다.

import { useEffect, useState } from "react";
import Layout from "../components/Layout";
import SubLayout from "../components/SubLayout";

CSR.getLayout = function getLayout(page) {
  return (
    <Layout>
      <SubLayout>{page}</SubLayout>
    </Layout>
  );
};

export default function CSR() {
  const [time, setTIme] = useState();
  useEffect(() => {
    setTIme(new Date().toISOString());
  }, []);
  return (
    <>
      <h1 className="title">{time}</h1>
    </>
  );
}

보는거와 같이 /csr 경로로 왔을때 "Home으로" 라는 문구가 생겼고 아래 footer나 css가 잡혀있는걸 확인할 수 있다.