Next.JS App Router 기반 이론 간단 설명

윤뿔소·2023년 10월 22일
1

Next.JS

목록 보기
1/3
post-thumbnail

Next.JS는 SSR을 제대로 구현하기 위해 기본적으로 리액트 18버전에서 나온 서버 컴포넌트를 활용해 렌더링 하고 있다.

리액트의 새 기술인 서버 컴포넌트를 잘 모른다면 참고를 참고해달라.

참고: 서버 컴포넌트 vs 클라이언트 컴포넌트

리액트에서 정의하는 서버 및 클라이언트 컴포넌트 차이점은 아래와 같다.

타입설명주의사항파일 네임 컨벤션
서버
  • 서버에서만 렌더링되는 컴포넌트
  • 유저 인터랙티비티 제공 불가
  • useState(), useReducer(), useEffect()와 같은 state / effects 사용 불가

  • ❌ DOM과 같은 브라우저 api 사용 불가
  • ❌ state / effects / 브라우저 api 사용하는 커스텀 훅 사용 불가

  • ✅ 데이터베이스 / 내부 서비스 / 파일시스템과 같은 server-only 데이터 사용 가능

  • ✅ 서버 컴포넌트 / 클라이언트 컴포넌트 / native elements (예: div, span) 임포트 및 렌더링 가능

  • ✅ 클라이언트 컴포넌트 props로 serializable한 데이터 전달 가능

Example.server.js
클라이언트
  • 클라이언트에서 렌더링 되거나 SSR을 통해 서버에서 렌더링 되는 컴포넌트

  • 유저 인터랙션 사용 가능
  • 서버 컴포넌트 도입 전 리액트 컴포넌트
  • ❌ 서버 컴포넌트 임포트 불가

    • 다만 서버 컴포넌트는 클라이언트 컴포넌트에게 또 다른 서버 컴포넌트를 자식으로 넘겨주는 건 가능 예) <ClientTabBar><ServerTabContent /></ClientTabBar>

  • ❌ server-only 데이터 사용 불가
  • ✅ state / effects / 브라우저 api 사용 가능
Example.client.js
공유
  • 서버와 클라이언트에서 렌더링 되는 컴포넌트
  • ❌ state / effects / 브라우저 api 사용 불가
  • ❌ 서버 컴포넌트 임포트 불가, server-only 데이터 사용 불가
  • ✅ 서버와 클라이언트 컴포넌트에서 임포트 되어 사용 가능
Example.js

물론 서버 컴포넌트가 아예 SSR 렌더링과 동일하다 할 수 없고, 클라이언트 컴포넌트는 클라이언트만 렌더링된다라는 것도 아니다.
일단 이해를 돕기 위해 서버/클라이언트 컴포넌트는 SSR, CSR 렌더링 방식의 차이라고 서술했지만, 자세히 들여다보면 다르다는 얘기다.


이러한 배경이 있었기에 Page Router 때는 Next.JS의 고유 함수들을 써야 SSR 방식을 채택한 렌더링이 됐었다.
이제 App Router는 지시어가 없으면 기본적으로 SSR 렌더링 방식을 취하는 서버 컴포넌트로 구동된다.

왜 서버 컴포넌트?

PHP나 제이쿼리 등의 시절에는 SSR이 새로고침에 의한 블링크로 UX가 매끄럽지 못함, 브라우저 및 개인 컴퓨터 구동 환경 스펙이 부족함 등으로 한계가 명확했다.

그래서 CSR 방식인 차세대 웹 개발 라이브러리인 리액트, 뷰, 앵귤러들이 그 자리를 메꿨다.
페이지를 이동할 때마다 로딩이 없어 매끄러움, 상태 및 이벤트 등의 사용자 경험을 위한 함수 용이 등으로 각광을 받았지만, 요즘은 다양한 라이브러리들이 추가됨에 따라 번들 크기 증가 및 JS 초기 로딩 증가로 한계를 맞았다.

그래서 HTML을 생성하고, 미리 UI를 보여줄 수 있는 SSR 방식이 다시 각광을 받았다. 그런 방식으로 사용할 수 있게 만든 프레임워크 Next.JS, Nuxt.JS가 득세하고 있었다.
리액트는 이 변화에 탑승하기 위해 RSC, 리액트 서버 컴포넌트 개념을 만들어 18버전에 업데이트 했다.

서버 컴포넌트는 서버에서부터 복잡한 인터페이스를 구축하는 동시에 클라이언트로 전송되는 JavaScript의 양을 줄여, 초기 페이지 로드 속도를 높일 수 있다.
즉, SSR 방식을 채택하여 SSR의 장점 이용 및 CSR 한계를 타파하기 위해 나왔다.

Next.JS에서 서버 컴포넌트

Next.JS에서는 'use client' 지시어를 사용하지 않으면 자동으로 서버 컴포넌트로 감지하여 사용한다.
만약 use로 시작하는 훅이나 이벤트가 포함돼있다면 'use client' 지시어를 사용하자.
그 외 다른 기준을 알고 싶다면 서버 상태 vs 클라이언트 상태를 봐보자. 상태 얘기긴 하지만 클라, 서버를 나누는 기준은 비슷하기에 위 글을 봐도 무방하다.

그리고 App Router는 app 폴더에서 폴더 + page.tsx 기준으로 URL 도메인을 나누고 라우팅이 이뤄진다.
또한 Next.JS의 라우팅 기능 및 generateStaticPropsMetadata 같은 애들은 서버 컴포넌트에서만 기능을 사용할 수 있다.

팁: App Directory 만들 때

위에서 언급했듯이 서버 컴포넌트만 쓸 수 있는 기능이 있다. 그래서 /src/app에서는 디렉토리를 짜는 파일만 만들고, UI나 use client 지시어를 사용할 만한 기능은 /component/container에 넣는 것이 좋다.

위 이미지는 내 실제 App Router 페이지인데, 동적 라우팅으로 SSG를 만들 때 쓰이는 generateStaticParams, Metadata이 있다.
저 두 기능들은 서버 컴포넌트, 즉, SSR 방식으로 렌더링해야지 적용할 수 있는 기능들이라 URL을 구성하는 파일만 저렇게 생성하고,

/containers부터 'use client' 지시어를 사용하는 모습이다.

이런 식으로 해야 나중에 메타 데이터나 서버 컴포넌트로서 사용할 기능들을 적용하기 쉬워진다.

profile
코뿔소처럼 저돌적으로

5개의 댓글

comment-user-thumbnail
2023년 10월 26일

오늘 마침 딱.. ssr 관련 문제에 봉착했었는데 복기하기 좋은 타이밍이였네용 ㅎㅎ 잘 보고 갑니다!

답글 달기
comment-user-thumbnail
2023년 10월 29일

아직 next.js를 써본적없었어 이런 개념이 있다는걸 볼수 있어서 유용하고 좋은거 같습니당 ㅎㅎ

답글 달기
comment-user-thumbnail
2023년 10월 29일

오늘도 유용한 개념 익히고 갑니다 ㅎ

답글 달기
comment-user-thumbnail
2023년 10월 30일

서버사이드가 많이 사용되게된 과정까지 알게되어서 좋았어용 ㅎㅎ

답글 달기
comment-user-thumbnail
2023년 10월 30일

서버사이드가 많이 사용되게된 과정까지 알게되어서 좋았어용 ㅎㅎ

답글 달기