[NEXT.js] 넥스트 JS를 배워보자 2편 - 공통 레이아웃

2022. 2. 20. 17:47Library,Framework

728x90

오늘은 Next JS에서 공통된 레이아웃 (Header, Footer 등 여러 페이지에서 반복적으로 사용되는 컴포넌트)를 정의하는 방법에 대해 설명해보려고 한다.

 

보통 React의 경우,

import Navbar from '/Navbar'

export default function Layout({ children }) {
  return (
    <div>
      <Navbar />
      <main>{children}</main>
    </div>
  )
}

 

이런 식으로 Layout이라는 페이지 컴포넌트(이름은 상관없음)를 정의하고

그 안에 공통적으로 사용될 컴포넌트를 넣어주는 방식을 사용한다. 

주로 Navbar, SideBar, Footer 이런 컴포넌트와 함께 공통적으로 들어갈 스타일링이 있다면 같이 해준다.

 

// ...생략
// App.js

export default const App = () => {
	return (
        <Layout>
            <section>
			{/*랜더링할 페이지, 컴포넌트*/}
            </section>
        </Layout>
    )
}

 

Next JS도 개념은 비슷하다.

 

일단 모든 페이지에 보일 하나의 공통적인 레이아웃이 필요하다면 pages/_app.js 엔트리 파일에 공통된 레이아웃을 정의해주면 된다.

 

Next JS에서 _app.js는 서버에 요청이 들어왔을 때 가장 먼저 실행되는 컴포넌트로서

주로  페이지에 적용할 공통적인 요소 (레이아웃, 상태 등을) 정의하기 위해 사용된다.

 

// pages/_app.js

import Layout from 'components/layout'

export default function MyApp({ Component, pageProps }) {
  return (
    <Layout>
      <Component {...pageProps} />
    </Layout>
  )
}

 

여기서 pageProps는 1편에서 언급한 데이터 fetching method인 getInitialPropsgetStaticPropsgetServerSideProps 중 하나를 통해 받아온 초기 속성 값이다. 

 

한마디로 페이지 요청을 받게 되면 해당하는 Component와 그 속성 값을 레이아웃과 함께 전달, 랜더링 해주는 방식이다.

 

만약 모든 페이지에 일괄적으로 적용되는 레이아웃은 아니고 부분적으로(또는 중첩)으로 적용해야 하는 레이아웃은 어떨까?

(ex. 마이페이지를 여러 페이지로 설계했는데 마이페이지 내에서만 적용되어야 하는 내비게이션).

 

이런 Per Page Layouts을 위해서는 속성을 하나 정의해주면 된다

공식문서에서는 getLayout이라는 속성을 정의해서 사용하고 있지만 이 역시 이름은 크게 상관이 없다. 

 

 

마이페이지 레이아웃 컴포넌트 (MyPageLayout)

 

const MyPageLayout = ({ children }) => {

return (
    <>
    <nav>
      <ul>
         <li>내정보</li> 
         <li>정보 변경</li>
      </ul>
    </nav>
       {/* 사이드바 등등 마이페이지 내에서 공통적으로 사용할 레이아웃 정의 */}
    </>
);

export default MyPageLayout;

 

위에 정의한 레이아웃을 적용할 페이지 (ProfileEdit)

 

import MyPageLayout from "layouts/MyPageLayout";

const ProfileEdit = () => {
  return (
    <section className={styles.edit}>
     {/* 프로필 수정 페이지 */}
    </section>
  );
};

ProfileEdit.Layout = MyPageLayout; // 속성이름은 상관없다. getLayout, Layout 등등
export default ProfileEdit;

 

_app.js

 

import Layout from "components/Layout"; // 전체 레이아웃

const MyApp = ({ Component, pageProps }) => {
  const EmptyLayout = ({ children }) => <>{children}</>; 
  const NestedLayout = Component.Layout || EmptyLayout;
  
  return (
    <Layout>
      <NestedLayout>
        <Component {...pageProps} />
      </NestedLayout>
    </Layout>
  );
};

export default MyApp;

 

이런 식으로 손쉽게 중첩된 레이아웃 구조를 정의할 수 있다.

 

출처: https://nextjs.org/docs/basic-features/layouts

 

Basic Features: Layouts | Next.js

Learn how to share components and state between Next.js pages with Layouts.

nextjs.org