멘토링 시간에 NextJs 서버 컴포넌트를 활용해보고 싶은데 상세페이지에서 사용하는게 옳은 방향인지 모르겠다는 밑도 끝도없는 고민을 털어놓았는데 멘토님이 수업 이후 이런 디엠을 보내주셔서 더 자세히 고민하게 되는 계기가 되었다.



서버 컴포넌트
클라이언트 컴포넌트
SSR은 서버에서 렌더링 된 HTML을 가져오지만,
서버 컴포넌트는 HTML이 아닌 렌더링 할 트리 객체를 가져온다는 점이다.
트리 객체는 서버 컴포넌트, 클라이언트 컴포넌트로 구성되어 있으며 트리를 보고 DOM을 업데이트한다고 한다.
서버 컴포넌트가 SSR을 대체할 수 있는건 아니다. SSR과 서버 컴포넌트가 함께 사용된다면, 초기에 서버에서 빠르게 렌더링한 다음, SSR을 통해 이를 HTML로 렌더링하여 웹 애플리케이션 초기 로딩을 빠르게 만들 수 있다. 따라서 RSC 반드시 둘 중 하나를 선택할 필요도 없고 필요에 따라 RSC와 SSR을 적절히 함께 사용하는것이 더욱 효과적일 것이다.
정적 사이트에서 발생했던 페이지 전환시 서버에서 즉각적으로 페이지 생성하면서 생기는 화면 깜빡임 문제가 여전히 존재한다.
서버에서 매 번 동적으로 계산하여 페이지를 렌더링하기에 서버 부하가 커지기 쉽다. 비용이 늘어나는 것도 마찬가지다.
⇒ SSG
DetailContainer : 데이터 페칭 + UI
→ DetailContainer를 서버컴포넌트로 유지하고 데이터 페칭만을 담당시키려 함. ‘use client’는 각 하위 컴포넌트로 옮기기 시도
결과:
DetailContainer에서 클라이언트 사이드 데이터 상태관리를 위해 Tanstack query의 useQuery를 사용하고 있기 때문에 서버 컴포넌트를 유지할 수 없게 됨[ Server ] Error: Attempted to call useQuery() from the server but useQuery is on the client. It's not possible to invoke a client function from the server, it can only be rendered as a Component or passed to props of a Client Component.
⇒ 컴포넌트 책임 분리
page.tsx: 서버 컴포넌트. 서버 사이드 로직과 초기 데이터 페칭DetailContainer.tsx: 클라이언트 컴포넌트. 클라이언트 상태 관리와 데이터 업데이트를 담당DetailPresenter.tsx: 상세페이지 UI 담당. 컴포넌트들을 렌더링모임 상세 페이지의 특성상 CSR(Client Side Rendering)이 더 적합해 보입니다. 그 이유는 다음과 같습니다:
예를 들어, 모임 정원이 10명일 때:
[SSR의 경우]
1. A사용자가 페이지 로드 시점에 참여자 8명 확인
2. 실제로는 2명이 더 참여해서 10명이 됨
3. A사용자는 여전히 8명으로 보이는 상태에서 참여 시도
4. 버그 발생
[CSR의 경우]
1. A사용자 화면에 실시간으로 10명이 반영됨
2. 참여 버튼이 자동으로 비활성화
3. 사용자 경험 향상