1. _app
- 참고 : https://nextjs.org/docs/advanced-features/custom-app
- 특징
- 가장 먼저 실행되는 컴포넌트입니다. (
_app
-> page component
-> _documnet
(Server side))
- 모든 페이지는 이 컴포넌트를 통합니다. (각 Route 구성 요소를 래핑하는 역할)
- 페이지에 적용할 공통 레이아웃 역할을 합니다. (ex header, footer, layout component 등)
- 페이지 전환 시 전체 레이아웃을 유지할 수 있습니다.
- 페이지 전환 후 상태를 유지시킬 수 있습니다.
- 글로벌 CSS를 적용시킬 수 있습니다.
- 추가적인 데이터를 페이지로 주입시켜주는게 가능합니다.
- 각종 Provider 설정할 수 있습니다. (ex Redux, Apollo 등)
- props로 받는 Component는 페이지에 보여줄 컴포넌트이며, 페이지 전환 시 이 props의 값이 변경됩니다.
- props로 받는 pageProps는 데이터 패칭 메소드를 통해 가져온 초기 객체입니다.
_app
내부에서는 getStaticProps 또는 getServerSideProps 메서드를 지원하지 않습니다.
_app
내부에 getInitialProps가 있는 경우 자동 정적 최적화가 비활성화 됩니다. 자동 정적 최적화란 요구사항이 없는 경우 자동으로 페이지를 정적으로 생성하는 것을 말합니다.
2. _document
- 참고 : https://nextjs.org/docs/advanced-features/custom-document
- 특징
_document
는 _app
다음에 실행되며, 공통적으로 활용할 head(ex meta태그)나 body 태그 안에 들어갈 내용들을 커스텀할 때 활용합니다.
- 폰트 import, CDN 등을 연결하여 사용할 수 있습니다.
- Document 클래스를 상속받는 클래스 컴포넌트로 작성해야한다는 규칙이 있습니다.
- 렌더 함수는 꼭 Html, Head, Main, NextScript를 포함해야 합니다.
- 페이지 별 공통적인 사항이 아닌 title같은 경우 app에서 처리합니다.
- 서버 사이드에서 동작하기 때문에 onClick과 같은 이벤트나, CSS 스타일 파일은 작동하지 않습니다. 테스트해보기 위해 useEffect hook을 사용하여 console에 문자열이 찍히는지 확인해보았는데 역시
_document
는 찍히지 않고 _app
은 찍힙니다.
- 커스텀이 필수는 아니며 커스텀하지 않을 경우 Next 모듈에 존재하는 document.js을 실행하게 됩니다.
- Head 컴포넌트 조작 시 import 위치를 주의해야 합니다.
_document
내부에 사용하는 모든 페이지에 공통적으로 적용시킬 Head의 경우 next/document에서 가져온 Head를 사용해야 합니다. 또 title 태그와 같이 페이지별로 다른 Head 설정을 할 경우에는 next/head에서 가져온 Head를 사용해야 합니다.
_app
과 마찬가지로 _document
내부에서는 getStaticProps 또는 getServerSideProps 메서드를 지원하지 않습니다.
_document
는 페이지 별 오버라이딩이 가능합니다. 하지만 공통으로 사용하고 있는 _document
가 있다면 페이지 별로 지정 된 _document
로 대체되어 문제가 발생할 수 있습니다.
3. 한 줄 정리
_document
는 정적인 상태로 적용시킬 공통 사항을 적용시킬 때 사용하며 react의 index.html
과 유사한 기능을 수행합니다. _app
는 동적인 상태로 적용시킬 공통 사항을 적용시킬 때 사용하며 react의 router 설정 컴포넌트와 유사한 기능을 수행합니다.
4. Next.js의 데이터 패칭 방식
Next.js의 pre-rendering(사전 렌더링)을 위한 데이터 패칭 방식은 크게 4가지가 있습니다. 각각의 데이터 패칭 방식을 통해 받아온 데이터는 컴포넌트에 props로 전달받아 사용할 수 있습니다.
- getInitialprops (SSR : Server Side rendering)
- 최초에 앱이 렌더링되거나, 클라이언트 라우팅이 일어나는 순간 데이터를 패칭합니다. getServerSideProps와 비슷하지만 route로 접근할 때 새로고침이나 직접 URL을 입력하는 방식으로 접근하면 서버에서, Next.js에서 제공하는 Link 컴포넌트를 통해 접근한다면 클라이언트에서 호출됩니다.
- getServerSideProps (SSR : Server Side rendering)
- 페이지 접근 시 매번 새로 데이터를 패칭합니다.
- getStaticProps (SSG: Static Site Generation)
- 빌드 시 데이터를 패칭하고 CDN에 캐싱하여 모든 요청에 재사용합니다. 빌드 된 디렉토리에 접근해보면 빌드 시점에 맞는 데이터가
index.html
에 채워져있는 것을 확인해볼 수 있습니다. 즉 빌드 시점 후에 서버에 데이터 변화가 일어나게 되면 빌드되지 않은 경우에는 데이터가 최신화되지 않습니다.
- development 환경에서 getStaticProps는 매 요청마다 실행되며 production 모드에서는 getStaticProps는 빌드 시 실행됩니다.
- getStaticProps + revalidate (ISR: Incremental Static Regeneration)
- getStaticProps 사용 시 Data의 최신화가 이루어지지 않는다는 단점이 있는데 revalidate 속성을 활용하여 해결할 수 있습니다. 초기에 캐싱 된 페이지를 보여준 후 revalidate 주기마다 데이터의 업데이트를 확인하여 페이지를 재생성합니다.
- 트래픽이 발생하면 재생성이 이루어지기 때문에 사이트를 이용하는 유저가 없는 경우 revalidate 주기를 넘어도 페이지가 재생성되지 않습니다.
5. 프로젝트 분석