Next.js의 구동방식을 알아보며 _app과 _document에 대해 알아보겠다.
_app / _document
위 두 파일은 없어도 Next의 실행에는 문제가 없다. 커스터마이징이 필요할 때 사용하게 되는 파일이다.
Server Only File으로, Next Client에서 사용하는 로직(eventlistener 등의 window/DOM 로직)을 사용하면 안된다. window is not defined 라는 에러를 보게 된다면 해당 사항을 체크해봐야 한다. (!!이 에러가 나는게 그래서였군..)
최초로 실행되는 것은 _app.js이다. 요청한 페이지를 먼저 Component에서 띄우게 된다.
그 다음 _document.js가 실행된다. _app.js에서 구성한 HTML이 어떤 형태로 들어갈지 구성하게 된다.
✏ _app
App 컴포넌트는 모든 페이지의 공통 페이지이다.
- 페이지들의 공통된 레이아웃
- 페이지를 탐색할 때 상태 유지
- 추가 데이터를 페이지에 주입
- 글로벌 CSS 추가
import React, { useEffect, useState } from "react";
import styled from "styled-components";
import Header from "../components/Header";
import Footer from "../components/Footer";
import GlobalStyle from "../styles/GlobalStyle";
const App = ({ Component, pageProps }) => {
return (
<>
<GlobalStyle />
<Header />
<Content>
<Component {...pageProps} />
</Content>
<Footer />
</>
);
};
const Content = styled.section`
display: block;
width: auto;
height: auto;
`;
export default App;
App 컴포넌트는 Component라는 props를 받게 되는데, Component는 불러오는 페이지이다.
Component는 pageProps를 props로 받고 있는데, 이는 pages 안의 파일에서 getServerSideProps, getStaticProps 혹은 getInitialProps로 페이지에 전달해주는 props이다.
✏ _document
Document 는 일반적으로 <html> 및 <body> 태그를 보강하는 데 사용된다. 모든 페이지의 공통 페이지이다.
- <title>, <meta> 등 정보를 제공하는 HTML 코드 작성
- 폰트 등의 외부 api, cdn 등을 불러옴
import Document, { Html, Head, Main, NextScript, DocumentContext } from "next/document";
import { ServerStyleSheet } from "styled-components";
export default 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
href="https://fonts.googleapis.com/css?family=Noto+Sans:400,700&display=swap"
rel="stylesheet"
/>
<script defer src="https://developers.kakao.com/sdk/js/kakao.js" />
</Head>
<body>
<Main />
<NextScript />
</body>
</Html>
);
}
}
✏ getServerSideProps / getStaticProps
웹 페이지에는 각 페이지마다 사전에 불러와야할 데이터들이 있다.
react 로직에 따라 componentDidmount / useEffect로 컴포넌트가 마운트된 후 Data Fetching 된다.
이 과정을 서버에서 미리 처리하도록 도와주는 것이 getInitialProps이다.
Next 9.3 이상부터는 getInitialProps보다 getServerSideProps / getStaticProps를 사용하는 것이 권장된다.
import fetch from "isomorphic-unfetch";
export const getServerSideProps = async ({ query }) => {
try {
const res = await fetch(`url`);
if (res.status === 200) {
const user = await res.json();
return { props: { user } };
}
return { props: {} };
} catch (e) {
console.log(e);
return { props: {} };
}
};
getServerSideProps는 이름 그대로 서버 측에서 props를 받아오는 기능을 하게 된다. 페이지 요청 시마다 실행되며 서버에서 실행되기 때문에 콘솔 출력이 터미널에서 되는 것을 확인할 수 있다.
getStaticProps는 getServerSideProps와 다르게 빌드 시에 데이터를 불러와 결과를 json으로 저장하여 사용하게 된다. 따라서 일관된 데이터를 보여주게 된다.
공통된 Data Fetching이 필요하다면 _app에, 페이지별로 필요하다면 페이지에 붙이면 된다.
다만, 한 페이지에는 하나의 getInitialProps 로직만 실행된다. 예를 들어 _app에서 사용하면 그 하부 페이지에서는 실행되지 않는다. 때문에 커스터마이징 과정이 필요하다.
이 부분은 아직 직접 코드를 통해 이해하지 못해서 글로 기록만 해 둔다. 예제로 구현하게 되면 첨부하도록 하겠다.
next.js 클론코딩 책과 다음 링크를 참조하여 작성했다.
Next js 구동방식 과 getInitialProps
Next js가 React Project의 SSR을 가능하게 한다. 라고는 하는데, 어떤 방식으로 SSR을 가능하게 할까, SSR과 CSR의 구분은 어떻게 되어 있을까.이 궁금증을 해결하기 위해, 먼저 알아야 할 것은 Next js의 구
velog.io
'main > Next.js' 카테고리의 다른 글
[React | Next.js] TOAST UI Editor 사용하기 (0) | 2022.01.10 |
---|---|
[Next.js] 기존 React 프로젝트 Next.js로 바꾸기 - 3 (TS, Styled-Component, SVG) (0) | 2021.12.22 |
[Next.js] 기존 React 프로젝트 Next.js로 바꾸기 - 1 (라우팅) (0) | 2021.11.28 |
eslint 관련 내용 (1) | 2021.11.23 |
eslint: command not found 에러 | .eslintrc.js (0) | 2021.11.22 |