[NextJS] _app.js & _document.js

hyo·2023년 5월 4일
0

NextJS

목록 보기
4/4
post-thumbnail

NextJS의 _app.js , _document.js에 대해

시작하며

우유부단 사이드프로젝트에는 React라이브러리와 NextJS 프레임워크를 도입하여 웹서비스를 만들었다.
NextJS에서 _app.js , _document.js 에 대해 알아보자.

_app.js 란?

NextJs에서는 App구성 요소를 사용하여 모든 페이지를 초기화한다.
즉, _app.js(tsx)를 만들어 기본 App 구성 요소를 덮어 쓰 수 있다. -> 모든 페이지에서 필요한 처리를 여기에 쓸 수 있다.(공통 컴포넌트)
  • 페이지 간의 공통 레이아웃을 설정 할 수 있다.
  • 공통 상태를 가질 수 있다.(Redux의 store)
  • Redux Provider 설정
  • 글로벌 CSS를 정의 할 수 있다.(모든 페이지에 적용될 CSS)
  • 각 Route 구성 요소를 래핑할 수 있다.(<Component {...pageProps} />)
// NextJS를 사용한 pages/ _app.tsx
import { GlobalStyles } from '../styles/globalStyle'; 
// -> style-reset라이브러리와 styled-components라이브러리의 createGlobalStyle을 사용한 파일을 불러옴.
import type { AppProps } from 'next/app';
// -> 래핑할 Component, pageProps 불러옴
import Layout from '../components/layout';
// -> 공통 컴포넌트로 사용할 Layout 컴포넌트 불러옴.
import Head from 'next/head';
// -> 페이지이름에 쓰일 수 있다.
import { store } from '../redux/store';
import { Provider } from 'react-redux';

export default function App({Component, pageProps}: AppProps) {
 
  return (
    <>
      <Head>
        <title>우유부단</title> // Head 설정
      </Head>
      <Provider store={store}> // Redux Provider store 설정
        <Layout> // Layout 공통 컴포넌트로 감싸준다.
          <GlobalStyles />
            <Component {...pageProps} /> // 각 Route 구성 요소 래핑
        </Layout>
      </Provider>
    </>
  )
  
}

위처럼 코드를 만들어 공통컴포넌트를 입히고 page Route를 할 수 있다.

_document.js 란?

NextJS는 서버사이드렌더링이다.
과연 서버에서 , 이런 태그들을 읽을 수 있을까??
읽게할 수 있게 _document.js에 설정을 해줘야한다.

  • SSR만의 실행이므로, 클라이언트측의 처리를 써서는 안된다.
  • Document는 서버에서만 렌더링되며, onClick같은 브라우저내장 매서드 등 이벤트 핸들러는 작동하지 않음.
  • <Main /> 안에 들어가는 외부 React 컴포넌트는 브라우저에 의해 초기화되지 않기 때문에 여기에서 애플리케이션 로직이나 styled-jsx, <title>,CSS 를 설정해서는 안된다. -> 모든 페이지의 컴포넌트에 공통으로 하고 싶은 경우는 App컴포넌트를 사용해야함. (_app.js)
  • document에서 title이나 공통으로 쓸 CSS를 넣는 실수는 하지말자.
// pages/ _document.tsx
  
import Document, {
  Html,
  Head,
  Main,
  NextScript,
  DocumentContext,
} from 'next/document';

import { ServerStyleSheet } from 'styled-components';

class MyDocument extends Document {
  static async getInitialProps(ctx: DocumentContext) {
    const sheet = new ServerStyleSheet();
    const originalRenderPage = ctx.renderPage;
    try {
      ctx.renderPage = () =>
        originalRenderPage({
          enhanceApp: (App) => (props) =>
            sheet.collectStyles(<App {...props} />),
        });

      const initialProps = await Document.getInitialProps(ctx);
      return {
        ...initialProps,
        styles: (
          <>
            {initialProps.styles}
            {sheet.getStyleElement()}
          </>
        ),
      };
    } finally {
      sheet.seal();
    }
  }

  render() {
    return (
      <Html>
        <Head>
          <link rel="icon" href="/image/favicon.ico" />
        </Head>
        <body>
          <Main />
          <NextScript />
        </body>
      </Html>
    );
  }
}

export default MyDocument;  
  

그리고 이건 구글링하다가 찾은건데 나도 이런 에러가 나왔었는지 기억은 안나지만,

위와 같은 에러가 나올시에
.eslintrc.json 여기 파일에서 밑에와 같이 추가를 해주면 된다고 한다.

profile
개발 재밌다

0개의 댓글