NEXT - JS

박상하·2024년 9월 25일

Next에 대해 학습을 진행하였다. 오랜 기간 프로젝트를 진행한 경험은 아니지만
Next의 특징에 집중하여 최대한 이해하려 노력했다.
필자가 이해한 내용을 바탕으로 Next Docs가 소개하는 Next의 특징 중 일부를 정리해보자 !

Next의 Docs를 보면

  • Routing
  • Rendering
  • Data Fetching
  • Styling
  • Optimizations
  • TypeScript

6가지의 대표적인 특징이 있다고 설명한다.

필자는 노마드코더 Next 기초강의를 수강하며 Next의 기본작동과 사용방법을 익혔다.

이를 통해 Routing, Rendering, Data Fetching에 대해 학습했다.

Next - Rendering

Next는 SSR을 지원한다. 기본적으로 Next의 모든 html은 server components로 만들어져 client로 보내진다.

이게 기본이다. 즉, backend에서 html을 만들어서 보내준다. Next는 React 프레임워크이다. 그렇다면 jsx코드가 html+js로 변환되고 이게 client로 넘어가는거다.

정리하면 다음과 같다.

클라이언트: 서버야 나 요청들어왔어 html 줘
서버: 어? 오케이 그릴게

이때 서버는 jsx = html + js로 분리한 후 html은 string으로
js는 그대로 client로 보내준다.

그럼 client는 html을 먼저 보여준다 (pre-rendering)
그 후 받아온 js파일을 가지고 hydration을 통해 리액트 컴포넌트로 변모된다.

Hydration ??

Hydration은 수분보충이라는 뜻으로 dummy html(interactive 하지않는 html)을 interactive하게 바꿔준다.

그런데 필자는 이 interactive에 꽂혀 hydration이 interactive하게 만들어주는거구나 라고만 이해했다.

그런데 그렇게 이해하는것보다 React Component로 변모시켜준다는 말이 더 와닿았다.

왜냐하면 예를들어 Link 라는 코드가 있다고 생각해보자.

return ( <div>
    <h1>Hello</h1>
    <li><Link href="/movie">Movie</Link></li>
    </div>)

위 코드는 필자가 느끼기에 interactive 한 html이라고 직관적으로 떠오르지 않았다.

그런데 위 코드는 이렇게 분리될 것이다.

//html
<div>
  <h1>hello</h1>
  <li><a href="/movie"></a></li>
 </div>  

의 html 파일과 Link라는 React Component에 대한 js chunk file

위 html과 js는 client에 보내지고 client에서 hydration이 일어나면 그때 페이지가 리로드되지 않고 routing이 가능한 React Component가 만들어지는 것이다.

(Link는 Next 모듈이 가지고 있는 React Components이다.)

SSG

Next는 SSR, SSG를 모두 지원한다. 사실 SSG를 사용하지는 않았지만 결국
HTML을 어느 시점에 만드는냐에 따라 SSR / SSG 로 나누어진다.

빌드타임에 HTML 만들어 놓기 -> SSG
요청받으면 HTML 만들기 -> SSR

이는 데이터를 패칭하는 시점에 따라 구분을 보통한다.
서버에서 미리 데이터를 페칭해온 HTML은 SSG
동적으로 요청이 들어왔을 때 데이터를 패칭한다면 SSR

그렇다면 예를 들어 공지사항같은 데이터는 SSG
동적 데이터 같은경우는 SSR로 처리하는게 좋을 거 같다.

Routing

Next는 프레임워크다. 사용방법을 따라 개발을 해야한다.
사실 Next를 사용하기 전에
React는 프레임워크인가 라이브러리인가에 대해 헷갈렸었다.
Next를 사용해보니 React는 라이브러리라는 확신이 든다.

Next의 주체는 프레임워크인 Next에게 있다. 개발자는 Next가 정해놓은 규칙을 잘 따라야한다. 대표적인 예시가 Routing이다.

우리가 React로 코드를 짤 때에는 각 컴포넌트를 Router의 path와 element로 연결해주어야했다. 직접 코드로 구현해야했는데 Next는
File System을 사용한다.

즉, 폴더구조에서 라우팅을 결정한다.
이게 그럼 무조건 적으로 좋은거냐? 그건 잘 모르겠다! 물론 라우팅을 하나하나 설정해주지 않아도 되는건 편리할 수 있으나, 정해진 규칙을 따르지 않으면 바로 오류가 발생한다.

우리가 Next의 Routing에서 얻을 수 있는 이점은 또 여러개가 있다.

Loading, Error, Layout, not-found

놀랍게도 page와 동일한 위치에 있는 loading, error, layout 파일은
자동으로 빌드되어 각각의 위치에서 활약한다.

예를들어
데이터 페칭이 있는 html의 경우 loading에 존재하는 html이 보여지고
에러가 있는 html의 경우 error에 있는 html이 보여지고
layout을 설정한 page는 page 위 layout html로 자리한다.
사용자가 요청한 page가 routing내에 존재하지 않을 때 not-found html이 보여진다.

궁금증 💭

필자는 이를 보고 서버가 그럼 Loading 페이지 보여주고
데이터가 담긴 페이지도 보여주는거니까 html을 2번 보내주는건가? 이렇게 생각했다.

Layout, Loading, Error, Not-Found와 같은 jsx(tsx)파일은
번들링 과정에서 js파일로 바로 보내질 준비가 되어있다.

그리고 만약 page가 존재하는 폴더로 client로부터 요청이 들어오면 그때 이미 번들링해놓은 Javascript가 전달되고 이를 이용해 client에서 loading, error등등 필요한 상황에 맞게 그린다.

Data Fetching

Next의 꽃인거 같다. data를 server에서 호출할 수 있다니
그렇다면 client는 데이터를 페칭하는 API도 몰라도되고 페칭하는 코드조차 넣지 않아도 된다. 보안적으로 더 좋지 않을까?

컴포넌트를 async-await로 처리할 수 있다.

무슨 말이냐면 데이터 페칭을 기다렸다가 ! ! !
컴포넌트를 렌더링할 수 있다는 말이다 ! ! !

이게 가장 흥미로웠다. 아 SSR의 맛이구나..

방법은 다양하다.

이런식으로 data fetching을 await 하면 된다.

그런데 사실 이것보다 좋은 방법이 있다.

Promise.all (논외🫢)

저렇게 코드를 짤 수 있지만 저렇게 짜게되면 하나의 API호출을 기다리고 해당 API가 호출되면 다음 API가 호출된다. API가 적다면 크게 상관없겠지만 만약 필요한 data fetching이 20개라면?? 19번을 기다릴건가?

이를 위해 Promise.all이 있다. Promise.all은 new Promise가 아닌 메서드이다.

Promise.all([데이터페칭함수1,데이터페칭함수2...])

이런식으로 사용하면된다.

JS interpreter는 논블록킹 싱글스레드 아니었어?

위를 보면 병렬적으로 API를 호출하고있다.
이게 어떻게 가능할까?

참고한 블로그

위 블로그를 보면 아주 잘 나와있는데, 간단히 말하면
이벤트 루프를 통한 비동기 방식으로 동시성을 지원하는 것이다.
브라우저 덕.

(필자도 좀 더 이해가 필요하다.)

Suspense도 지원

Suspense는 React component로 fallback 속성을 통해 Suspense내부의 컴포넌트를 기다려준다. 그런데 이 Suspense를 넥스트에서 지원한다.

즉 Suspense는 컴포넌트의 로더 기능을 할 수 있다.

아까 page와 동일한 폴더에서 loading 파일이 페이지의 로더가 되어주었다면
Suspense는 컴포넌트 단위의 로더가 가능하게 한다.

이런식으로 사용할 수 있다.

과정은 다음과 같다.

Suspense는 Next가 빌드타임에 js번들 파일로 빌드해준다.
(각 js번들파일은 해당 page의 폴더에 위치한다.)
그러면 요청받은 page에 Suspense가 있다면 js번들 파일이 먼저 client로 보내지고 이때 클라이언트에서는 js파일을 가지고 Suspense React Component를 구성한다. 그리고 내부의 컴포넌트에 있는 data fetching이 마무리되면 서버는 html을 보내주고 이때 React component로 존재하는 suspense의 내부 html은 fallback의 html에서 data가 존재하는 html로 교체된다.

이런식으로 Next는 Suspense를 통해 컴포넌트 단위의 SSR을 지원할 수 있는 것이다. 이렇게 병렬적으로 데이터를 패칭하고 컴포넌트를 렌더링 할 수 있다.

마무리

겉핥기의 Next 학습이지만 Next가 꽤 유용한 도구라는 점은 알 수 있었다.
이제 Next로 프로젝트를 진행해보면서 좀 더 친해져야겠다.

아직 어떤 데이터페칭을 어디서할지, 또 ssg/ssr에 대한 고민 등 이외에 Next의 특징과 장/단점을 직접 사용하면서 느껴봐야겠다.

다음 게시글은 아마 Next를 사용하며 배운점이 되지 않을까싶다.

0개의 댓글