My Boundary As Much As I Experienced

Next.js의 getStaticProps/getServerSideProps 완전 정리 본문

FrontEnd/Next.js

Next.js의 getStaticProps/getServerSideProps 완전 정리

Bumang 2024. 4. 28. 18:10

지금까지 나는 React을 활용하면서 배포과정이라던가 캐싱 같은 부분을 vercel같은 편리한 배포툴에 의존하는 편이었다.

그래서 Next.js 등을 배우면서 SSR, SSG의 개념을 처음 접하게 되었고, getStaticProps, getServerSideProps, getStaticPath들의 사용법도 처음 알게되었다. 이게 이론적인 설명만 들을 땐 '아하 그런거구나' 싶더라도 '결국 코드로 구현했을때는 어떻게 되는건데?', "왜 이렇게 설계되어있는거지?" 등의 의문이 계속 있게 되었다.

 

그러나 Udemy React/Next 강의를 들으며 조금 더 제대로 정리하게 되었고 이를 적어보려한다.

 

 

getStaticProps란?

정적 페이지(Static Site Generation)를 빌드할 때 사용한다.

이름 그대로, getStaticProps는 이 페이지에서 사용할 props를 만들어 페이지 컴포넌트에 전달한다.

(getStaticProps -> component)

정적페이지
정적페이지란 무엇일까? 주로 get요청 위주의 정보전달용의 페이지들을 이야기한다.
사용자와 상호작용할 여지가 적다.
각 사용자가 crud를 적극적으로 하고 이를 다른 사용자가 빠르게 확인해야되는 동적인 페이지가 아닌 경우가 정적페이지이다.
(회사 소개, 연혁, 블로그 등...)

 

 

getStaticProps의 장점

// 예시
export async function getStaticProps(context) {
  return {
    props: {
      yourId: {
      	id: "bumang",
        password: "1234567890"
      },
    },
  };
}

 

1. getStaticProps는 클라이언트에 노출되지 않는다. (보안 굳)

getStaticProps는 서버사이드에서 돌아가는 코드이며, 클라이언트에 노출되지 않는다. 그래서 보안이 뛰어나다.

심지어 database에도 안전하게 접속 가능하다고 한다.

 

2.  getStaticProps는 빌드 시의 데이터를 기준으로 데이터를 고정시켜놓는다. (성능 최적화)

클라이언트 사이드에서 useEffect를 쓸 때, 각각의 state변경, 동적으로 재할당이 빈번히 일어난다.

페이지를 요청할 때마다 빌드 시의 데이터를 기준으로 데이터를 고정시켜놓는다.

데이터베이스에 데이터가 계속 쌓인다고 해도 빌드를 새로 안 한다면 가장 마지막 빌드 시점의 데이터로 계속 고정되어 있다.

 

이게 왜 장점이냐고 물어볼 수 있다. 언제나 가장 최신의 데이터를 보여줘야하고, 사용자들끼리 서로서로 정보공유하며 crud를 대차게 하는 사이트에서는 이런 ssg를 사용할 수 없다. 그러나 회사 연혁, 소개 페이지 등 단순 get요청만 하는 페이지는 ssg가 선호될 수 있다.

페이지를 요청마다 다시 생성하는 ssr이나 csr이 아니라, 이미 만들어진 사이트를 빠르게 반환하는 ssg가 빠르고 효율적인 것이다.

 

ssr, csr은 사용자가 원하는 메뉴를 그때그때 주문받아 만들어서 공급하는 방식이고, ssg는 딱 고정된 메뉴 하나를 미리 만들어놓고 사용자가 주문 하자마자 나눠주는 느낌이다.

 

 

getStaticProps의 특징

1. 페이지 컴포넌트에서만 쓸 수 있다.

- 즉 pages router라던가, app router 폴더 안에 있는 컴포넌트들만 사용이 가능하다는 것이다.

 

2. 정해진 이름이다.

- getSuperStaticProps 이런 식으로 원하는대로 사용 불가능하다. getStaticProps라고 해야된다.

 

3. async로 설정 가능하다.

- async로 설정 가능하다. 그 말은 비동기 서버 호출을 한 후 그 결과값을 props로 사용할 수 있다는 점이다. 그러나 빌드 시의 데이터로 고정된다.

 

4. return하는 값은 { props: { ... }}에 담겨야한다.

- 이것도 'superProps: { ... }' 이런 식으로 사용할 수 없다. props: { ... } 라는 틀에 담겨서 컴포넌트로 넣어야한다고 Next.js팀이 정해놓은 것이니 따라야한다. (한국어에서 '은/는/이/가' 구별하기 싫다고 모든 조사를 내 맘대로 '냥'이라고 바꿀 수 없는 것과 비슷한 것이다.)

 

5. revalidate를 통해 언제까지 현재 빌드 데이터를 유지할건지 설정할 수 있다.

빌드 시 데이터로 고정하고 싶지만, 특정 주기 별로 갱신시키고 싶을 수도 있다. 예를 들어 1시간 단위마다 빌드하고 그 빌드된 데이터를 유지하고 싶을수도 있을 것이다. 이런 경우 revalidate 속성에 원하는 시간(초 단위)을 넣으면 된다.

  ...
  return {
    // 좋든 실든 props라는 객체에 원하는 값을 넣어줘야한다.
    props: {
      bumang: "male",
    },
    // revalidate는 현재 빌드 상태를 몇 초간 유지할건지?를 설정한다.
    // 리액트쿼리의 staleTime과 비슷한 개념.
    // 이 속성을 사용하면 매번 배포하지 않아도 된다.
    revalidate: 3600,
  };
}

 

 

getStaticProps의 객체 파라미터 context 객체 구성

 

getStaticProps는 객체 파라미터로 context라는걸 받을 수 있다. context는 아래와 같은 속성들을 가지고 있다.

  1. params: 페이지 경로가 동적 라우트를 포함하는 경우 (pages/posts/[id].js와 같이), params는 빌드 시 각 페이지에 해당하는 경로 파라미터를 포함한다. 예를 들어, getStaticPaths(이에 대해선 나중에 또 포스팅하겠다)에서 반환된 { params: { id: '123' } }는 getStaticProps의 context.params를 통해 { id: '123' }로 접근할 수 있다.
  2. preview: 페이지가 프리뷰 모드로 렌더링되는지 여부를 나타낸다. 프리뷰 모드는 CMS에서 미리보기 기능을 제공할 때 유용하다.
  3. previewData: 프리뷰 모드가 활성화된 경우, 프리뷰 데이터가 이 속성을 통해 전달된다. 이 데이터는 setPreviewData 함수를 통해 설정된다.
  4. locale, locales, defaultLocale: 국제화(i18n)가 설정된 Next.js 애플리케이션의 경우, 이 속성들은 요청에 사용된 로케일(locale), 사용 가능한 모든 로케일(locales), 기본 로케일(defaultLocale) 정보를 제공한다.

 

 

getServerSideProps란?

서버 사이드 렌더링(Server Side Rendering)을 구현하기 위해 쓴다.

getServerSideProps도 getStaticProps처럼 props를 생성하여 페이지 컴포넌트에 전달하는 것은 똑같다.

(getServerSideProps -> component)

 

 

 

getServerSideProps의 장점

// 예시
export async function getServerSideProps(context) {
  const req = context.req
  const res = context.res
  // able to do something with req, res ...

  return {
    props: {
      yourId: {
      	id: "bumang",
        password: "1234567890"
      },
    },
  };
}

 

1. getServerSideProps도 클라이언트에 노출되지 않는다. (보안 굳)

getServerSideProps도 (getStaticProps처럼) 서버사이드에서 돌아가는 코드이며, 클라이언트에 노출되지 않는다. 그래서 보안이 뛰어나다. database에도 안전하게 접속 가능하다고 한다.

 

2.  getServerSideProps는 Pre-rendering을 통해 SEO성능은 잡으면서 매 요청마다 신선한 데이터를 유지할 수 있다.

ssg와 csr의 장점을 중간에서 취한 느낌이다. csr에서 useState를 사용하는 것처럼 사용자의 조작에 따라 state를 계속 바꿀수는 없지만

페이지 get요청이 올 때 마다 신선한 데이터를 유지할수도 있고, SSG처럼 내용물이 차있는 페이지를 처음부터 불러오기 때문에 SEO 최적화에도 유리하기 때문이다.

 

즉, 사용자가 동적으로 조작할 state가 없는 get 요청 위주의 페이지이지만 데이터는 최신으로 계속 유지되어야하는 페이지에서 주로 쓰인다.

 

 

 

getServerSideProps의 특징

1. 이것도 페이지 컴포넌트에서만 쓸 수 있다.

- 즉 getStaticProps처럼 pages router라던가, app router 폴더 안에 있는 컴포넌트들만 사용이 가능하다.

 

2. 이것도 정해진 이름이다.

- getSuperServerSideProps 이런 식으로 원하는대로 사용 불가능하다. getServerSideProps라고 해야된다.

 

3. 이것도 async로 설정 가능하다.

- async로 설정 가능하다. 그 말은 비동기 서버 호출을 한 후 그 결과값을 props로 사용할 수 있다는 것이다. 그리고 getStaticProps와는 다르게 최신 데이터를 계속 불러올 수 있다.

 

4. return하는 값은 { props: { ... }}에 담겨야한다.

- 이것도 'superProps: { ... }' 이런 식으로 사용할 수 없다. props: { ... } 라는 틀에 담겨서 컴포넌트로 넣어야한다고 Next.js팀이 정해놓은 것이니 따라야한다.

 

 

getServerSideProps의 객체 파라미터 context 객체 구성

 

getServerSideProps도 객체 파라미터로 context라는걸 받을 수 있다. context는 아래와 같은 속성들을 가지고 있다.

getStaticProps에 비해서, req/res 등 node.js express에서 사용되는 것과 유사한 속성을 활용할 수 있고, query등에서 패러미터를 추출할 수 있는 등의 추가적인 활용방안이 존재한다.

  1. params: 페이지 경로가 동적 라우트를 포함하는 경우 (pages/posts/[id].js 등), params는 페이지 경로의 동적 부분에 해당하는 파라미터 값을 포함한다. 예를 들어, /posts/123 요청에서 params는 { id: '123' }의 형태를 가질 것이다.
  2. req: 요청 객체(IncomingMessage 타입)로, HTTP 요청의 헤더, 메소드 등과 같은 정보를 포함한다. 이를 통해 쿠키, 인증 정보 등을 읽을 수 있다.
  3. res: 응답 객체(ServerResponse 타입)로, 응답을 설정하는 데 사용된다. 예를 들어, 특정 HTTP 상태 코드를 설정하거나 쿠키를 추가하는 등의 작업을 할 수 있다.
  4. query: 요청 URL의 쿼리 문자열이 파싱되어 객체로 제공된다. 예를 들어, /posts?id=123 요청의 경우, query는 { id: '123' }를 가진다.
  5. preview: 페이지가 프리뷰 모드에서 실행 중인지 여부를 나타낸다. CMS 프리뷰 기능을 구현할 때 사용된다.
  6. previewData: 프리뷰 모드가 활성화된 경우, setPreviewData를 통해 설정된 프리뷰 데이터를 포함한다. 이 데이터는 프리뷰 세션과 관련된 정보를 포함할 수 있다.
  7. resolvedUrl: 쿼리 파라미터가 적용된 요청 URL이다. 예를 들어, 요청 URL이 /posts/abc?foo=bar인 경우 resolvedUrl은 /posts/abc?foo=bar가 된다.
  8. locale, locales, defaultLocale: 국제화(i18n) 설정이 활성화된 경우, 요청에 사용된 로케일(locale), 사용 가능한 모든 로케일(locales), 기본 로케일(defaultLocale) 정보를 제공한다.