페이지는 서버가 그림
페이지 내부 동적인 데이터를 패치하는 과정은 CSR
그렇기 때문에 만약 페이지가 로드될 때 함께 데이터가 패칭되어야 하는 상황이라면(pre-rendering)
next.js의 데이터 패칭 방식 (getInitialProps, getStaticProps, getStaticPath, getServerSideProps)을 이용해 첫 렌더에 데이터가 패칭될 수 있도록 처리
_app.js에서 전역적으로 데이터 패칭을 할 경우, getStaticProps나 getServerSideProps를 지원하지 않기 때문에 getInitialProps를 이용해야 합니다. 사실 지원하지 않는 것에는 그럴 만한 이유가 있기 때문이지만, 혹시나 사용할 수도 있으니 두 가지 방법을 모두 정리해보았습니다.
⚠️ 주의 ⚠️ : _app에서 getInitialProps를 사용해 모든 페이지에서 사용할 공통 속성값을 지정할 수 있으나, 이럴 경우 자동 정적 최적화(Automatic Static Optimization)이 비활성화되어 모든 페이지가 서버 사이드 렌더링을 통해 제공됩니다.
출처: 공식문서
Next는 기본적으로 데이터 요구 사항이 없는 경우 페이지가 정적인지 자동으로 확인하고, getInitialProps나 getServerSideProps를 사용하지 않는다면 페이지를 정적 HTML로 사전에 렌더링하여 자동으로 페이지를 최적화합니다.
자동 정적 최적화 : getInitialProps가 없으면, 페이지를 정적 HTML 으로 사전렌더링 해서 정적 최적화를한다. SSR 계산이 없기 때문에 사용자에게 즉시 뿌려지는 ultra fast 로딩이다.
그러나 전역적으로 getInitialProps를 사용하게 되면, 이러한 최적화과정이 일어나지 않습니다. 때문에 Next.js 9.3버전 이후엔 이런 것을 방지하고자 SSR과 SSG를 분리해 getStaticProps / getServerSideProps로 나눠졌으며, 전역적인 데이터 패치 기능을 지원하지 않습니다. 따라서 전역적으로 SSR의 데이터 패칭을 해야만 하는 경우라면 getInitialProps를 써야만 전역적인 패치가 가능합니다. (Next에서 추천하는 방식 x )
기본적으로 getInitialProps를 비롯한 데이터 패칭 메소드들은 리턴한 값을 해당 컴포넌트의 props로 보냅니다. getinitialProps는 context를 기본 props로 받는데, 그 내부엔 ctx객체와 Component가 존재합니다. Component는 해당 컴포넌트를 의미하며, Component로 보내는 ctx 객체의 구성은 다음과 같습니다.
pathname - 현재 pathname /user?type=normal page 접속 시에는 /user
query - 현재 query를 object형태로 출력 /user?type=normal page 접속 시에는 {type: 'normal'}
asPath - 전체 path /user?type=normal page 접속 시에는 /user?type=normal
req - HTTP request object (server only)
res - HTTP response object (server only)
err - Error object if any error is encountered during the rendering
⚠️ 주의 ⚠️
getInitialProps 내부 로직은 서버에서 실행되기 때문에 Client에서만 가능한 로직은 피해야 합니다. (Window, document 등)
한 페이지를 로드할 때, 하나의 getInitialProps 로직만 실행됩니다. 예를 들어 _app.js에 getInitialProps를 달아서 사용한다면 그 하부 페이지의 getInitialProps는 실행되지 않습니다.
따라서 커스터마이징을 통해 따로 처리해줘야 합니다.
이런 것들을 고려해보았을 때, 이렇게 _app.tsx를 건들여서 데이터 패칭을 하는 것은 모든 페이지에서 전역적으로 가져와야 하는 데이터가 일괄적일 때 이외엔 지양하는 편이 좋다는 것을 알 수 있습니다.
사실 페이지 별로 데이터 패칭하는 것도 getInitialProps로 가능합니다. 그러나 그것이 정적데이터인지, 페이지 요청마다 렌더되는 데이터인지에 따라 그 방식을 분리한 것이
- getStaticProps : 빌드시 고정되는 값으로 빌드 이후에는 수정 불가
- getStaticPath : 동적라우팅 + getStaticProps를 원할 때 사용
- getServerSideProps : 빌드와 상관없이, 매 페이지 요청마다 데이터를 서버로부터 가져옴
이며, 9.3버전 이후 Next에선 이 세 가지를 이용하는 것을 권고하고 있습니다. 따라서 getInitialProps가 아닌, 이 셋을 이용하는 방식을 정리해보았습니다.
params: 다이나믹 라우트 페이지라면, params를 라우트 파라미터 정보를 가지고 있다.
req: HTTP request object
res: HTTP response object
query: 쿼리스트링
preview: preview 모드 여부 >공식문서
previewData: setPreviewData로 설정된 데이터