본문 바로가기

Front-End: Web/React.js

_app와 _document

반응형

Recap

_app과 _document

  • Next.js의 기본 페이지
  • 페이지에 공통적으로 적용될 내용들을 작성
  • _app은 로적, 전역 스타일 등 컴포넌트에 공통 데이터를 다룸
  • _document는 공통적으로 적용할 HTML 마크업을 중심으로 다룸

 


 

 

_app

  • 서버로 요청이 들어왔을 때 가장 먼저 실행되는 컴포넌트
  • 페이지에 적용할 공통 레이아웃의 역할을 함

 

주 사용 목적

  • 모든 컴포넌트에 공통적으로 적용할 속성 관리
function MyApp({ Component, pageProps }) {
  return <Component {...pageProps} />
}

export default MyApp

 

규칙

  • Component 속성값 → 서버에서 요청한 페이지
  • pageProps 는 아래 세 개 중 하나를 통해 페칭한 초기 속성값이 된다.
    • getInitialProps
    • getStaticProps
    • getServerSideProps
  • _app 에서도 getIntiialProps 로 모든 페이지에서 사용할 공통 속성값을 지정할 수 있지만,
  • 그러면 자동 정적 최적화(Automatic Static Optimization)이 비활성화 되기 때문에 모든 페이지가 서버 사이드 렌더링을 통해 제공된다.
  • 만약 _app 에서 getInitialProps 를 사용하려고 하면, 다음과 같이 App 객체를 불러온 후, getInitialProps 를 통해 데이터를 불러와야 한다.
import App from 'next/app'

function app({ Component, pageProps }) {
    return <Component { ...pageProps } />
  }
   
app.getInitialProps = async (appContext) => {
  const appProps = await App.getInitialProps(appContext);
  
  return { ...appProps }
}

 

 

 

_document

  • _app 다음에 실행됨
  • 공통적으로 활용할 <head>(ex. 메타 태그) 나 <body> 태그 안에 들어갈 내용들을 커스텀할 때 사용

 

주 사용 목적

  • 폰트 임포트
  • charset
  • 웹 접근성 관련 태그 설정
// 기본적인 _document의 형태

import Document, { Html, Head, Main, NextScript } from 'next/document'

class MyDocument extends Document {
  static async getInitialProps(ctx) {
    const initialProps = await Document.getInitialProps(ctx)
    return { ...initialProps }
  }

  render() {
    return (
      <Html>
        <Head />
        <body>
          <Main />
          <NextScript />
        </body>
      </Html>
    )
  }
}

export default MyDocument

 

규칙

  • Document 클래스를 상속받는 클래스 컴포넌트로만 작성해야 함
    • 렌더 함수는 <Html>, <Head>, <Main>, <NextScript> 요소를 리턴해줘야만 함
    • ⇒ import ~ from ‘next/document’
  • <Head> 태그 역시 next/head가 아닌 next/document 모듈에서 불러와야 함
    • <Head> 태그에는 모든 문서에 공통적으로 적용될 내용이 들어가야 함
    • ex. charset, 뷰포트 메타태그 등
    import Document, { Html, Head, Main, NextScript } from "next/document";
    
    export default class MyDocument extends Document {
    
      render() {
        return (
          <Html>
            <Head>
              <!-- 모든 페이지의 제목이 C17AN's Devlog로 변합니다. -->
              <title>C17AN's Devlog</title>
              <meta charSet="utf-8"></meta>
              <body>
                <Main />
                <NextScript />
              </body>
            </Head>
          </Html>
        );
      }
    }
    
  • 언제나 서버에서 실행되어야 함 → 브라우저 api 혹은 이벤트 핸들러가 포함된 코드는 실행되지 않음
    • <Main />을 제외한 부분은 브라우저에서 실행되지 않음
    • 따라서 이곳들에 비즈니스 로직을 추가해서는 안됨!
    • 또한 getStaticProps, getServerSideProps 를 통해 데이터를 불러올 수 없음

 


 

 

참고 자료

Next.js의 _document와 _app에 대하여

반응형