[NextJS] NextJS로 blog 만들어보기 - (2)

yongkini ·2023년 6월 23일

NextJS

목록 보기
2/4

nextjs에서 스타일링하기

  • 기본 적으로 styled-jsx 를 쓸 수 있는듯 하다(global로도 할 수 있고)
  • tailwindcss 도 프로젝트 만들 때 물어보는 것보면 당연히 지원하는 것 같다.
  • css-module도 지원하는데, 이걸 써보고자 한다.
  • 물론 PostCSS 등등 다른 것도 쓸 수 있다.

Pre-rendering / Data Fetching

: nextJS에서 핵심이 되는 개념들이다.

nextjs를 활용하면 페이지별로 pre-rendering 방식을 선택할 수 있다.

  • getStaticProps를 사용하면 SSG
  • getServerSideProps를 사용하면 SSR
  • 당연히 CSR도 가능
  • ISR 도 가능

중요한건 페이지 별로 프리 렌더 혹은 렌더 방식을 정할 수 있다는 것

SSG

SSG를 사용하면 좋은 페이지

: 정적인 페이지

  • Marketing pages
  • Blog Posts
  • E-commerce product listings
  • Help and Documentation

SSG 적용 여부의 기준점

  • 사용자가 페이지를 요청하기 전에(build 시기에) pre-render 할 수 있는가? 즉, 유저 인터랙션에 따라 결정되는게 아닌 static한 페이지인가?
    • yes 이면 SSG
    • No 이면 SSR or ISR 혹은 CSR

SSG의 2가지 케이스

  • 외부 데이터 없이 pre-rendering(정말 순수하게 정적인 페이지)
  • 외부 데이터를 가져와서 pre-rendering
    • 다른 파일
    • API
    • DB 등등..
export async function getStaticProps() {
  // getStaticProps 내에서 url은 상대경로로 줄 수 없다!
  const response = await fetch('http://localhost:3000/api/posts')
  const json = await response.json()

  return {
    props: {
      allPostsData: json.allPostsData,
    },
  }
}

data를 fetching 하는데 static 한 페이지라는게 이해가 좀 안됐는데, build 과정에서 호출해서 가져오는걸 말하는 것 같다. 실제로 빌드할 때

(SSG)     automatically generated as static HTML + JSON (uses getStaticProps)

이렇게 나온다.

SSG로 Dynamic Routes 만들기

: 일단 여기서 새롭게 써볼건 getStaticPaths 이다. SSG 를 씀과 동시에 dynamic path 를 쓰려면 사전에 빌드를 할 때 어떤 path로 만들어줄지 등을 정해놔야하는데 이걸 getStaticPaths에서 해준다.

getStaticPaths

: SSG는 build 할 때 페이지를 그려놓고 준비해놓는거라고 했었다. 이 때, 다이나믹 라우팅을 구현하려면? 즉, 어떤 url endpoint가 올지 모르는 상황에 해당 페이지를 그려놔야 한다고 하면, 이에 대해 build 할 때 next에게 알려주는 절차가 필요할 것이다. 예를 들어, domain/first/a 라는 url에서 a가 들어왔을 때는 어떤 페이지, b가 들어왔을 때는 어떤 페이지 이렇게 알려줘야 그에 대한 대비를 한다(페이지를 그려놓는다). 이 때, 어떤 페이지가 들어올지를 정해놓는 곳이 getStaticPaths 이다. 여기서

export async function getStaticPaths() {
  return {
    paths: getAllPostIds(),
    fallback: 'blocking',
  }
}

이런식으로 설정을 해놓으면 되는데 paths에는 이러한 형태의 배열이 들어간다.

   [
     {
       params: {
         fileName: 'ssg-ssr'
       }
     },
     {
       params: {
         fileName: 'pre-rendering'
       }
     }
   ]

fileName은 내가 다이나믹 라우팅을 위해 파일명에 [fileName].js 로 세팅해놨고, 거기에 어떤 값이 들어갈지를 저렇게 키와 값으로 세팅해놓은 것이다. 이제

export async function getStaticProps({ params }) {
  // 이렇게 여기서 params를 받을 수 있다.
  const postData = await getPostData(params.fileName)
  return {
    props: {
      postData,
    },
  }
}

getStaticProps의 props의 params로 해당 fileName을 받아서 어떤 처리를 할 수 있고 그에 따라 각각의 페이지를 그려놓을 수 있게 된다. 내가 만든 케이스의 경우 a라는 파일명이 들어오면 그에 따른 파일을 열어서 파싱한 데이터를 보여주고, b도 마찬가지로 처리한다. 이 때, a도 b도 아닌 값이 들어오면 어떻게할까? 그러한 상황을 대비해 fallback 옵션이 있다.

fallback

: 빌드시에 생성되지 않은 페이지에 대한 처리를 하는 옵션
- false : 처리하지 않는다. 404 에러
- true : callback 동작으로 loader를 보여줬다가 데이터가 있다면 그 때 그리겠다.
- blocking을 하면 loader도 없이 안그리다가 제너레이션 되는 순간 그리겠다

true, blocking을 해놓으면, 예를 들어, 기정의해놓지 않은 c라는 값으로 접근하면 true로 해놨을 때는 loader를(로딩 스피너 같은 것) 보여주면서, 그 때는 데이터가 있다면 그 때 그리는걸로 한다. 이것도 서버에서 처리를 하겠지만, SSG는 build 때 그리는 것이라는 점에서는 좀 다르다. 그 당시에 유동적으로 생성하는 거니까. blocking은 loader를 안그리다가 그릴 수 있게 되면 그리는 형태이다. 예를 들어, 갑자기 c라는 데이터가 생겼을 경우가 이러한 경우에 해당될 것 같다. 실제로 blog 플젝을 하면서 CRUD의 Create 기능을 만들었는데, 이렇게 없던 데이터가 생겼을 때 blocking or true option을 fallback에 주니까 일정 시간 동안 해당 페이지를 그리고 그 페이지로 이동시키는 것을 볼 수 있었다(false로 하면 실제 데이터는 추가됐는데, 404 에러를 리턴함)

추가로 알고 갈것

: fetch() promise는 HTTP Error 에 의해 reject 되지 않는다. 즉, fetch.then 등을 쓸 때 끝에 catch를 써도 http 요청에 대한 응답에서 error가 났을 때 이를 catch에서 잡을 수 없다. 그래서 특정 상황에 예를 들어, response.ok === false 이런 상황일 때
throw new Error('Fetch Error') 를 써서 에러를 일으켜야 then.catch에서 캐치할 수 있다. or http request 문을 try에 넣어놓고 catch문에 throw new Error('Fetch Error') 하는 방법도 있다.

profile
Web3.0에 관심이 많은 FE 개발자입니다. VPA와 캔들 차트 분석을 기반으로 정량적 트레이딩 시스템을 직접 개발하여 암호화폐를 트레이딩하고 있습니다.

0개의 댓글