배경
Next.js로 개발한 템플릿 기반 웹 애플리케이션에서 하이드레이션 오류를 경험했습니다.
이 애플리케이션은 다양한 블록 타입(텍스트, 이미지, 캘린더 등)을 포함한 템플릿을 렌더링하는 기능을 가지고 있었습니다.
특히 문제가 발생한 부분은 캘린더 컴포넌트였습니다.
서버에서 렌더링된 HTML과 클라이언트에서 렌더링된 HTML이 일치하지 않아 다음과 같은 오류 메시지가 발생했습니다.
Error: Hydration failed because the server rendered HTML didn't match the client.
오류 메시지를 자세히 살펴보면, 캘린더 컴포넌트의 ID 값과 클래스 이름이 서버와 클라이언트에서 다르게 생성되고 있었습니다.
특히 날짜 관련 데이터(`Date` 객체)를 사용하는 부분에서 불일치가 발생했습니다.
이러한 하이드레이션 오류는 서버 사이드 렌더링(SSR)과 클라이언트 사이드 렌더링(CSR) 사이의 불일치로 인해 발생하며, 특히 날짜, 시간, 랜덤 값과 같이 서버와 클라이언트에서 다르게 계산될 수 있는 동적 데이터를 다룰 때 자주 발생합니다.
이 문제는 사용자 경험에 직접적인 영향을 미치지는 않았지만, 개발 콘솔에 오류가 표시되고 React가 컴포넌트를 다시 렌더링해야 했기 때문에 성능 저하를 초래했습니다.
또한 이러한 오류는 애플리케이션의 안정성과 신뢰성에 대한 우려를 불러일으킬 수 있습니다.
이 문제를 해결하기 위해 Next.js의 다이나믹 임포트(dynamic import) 기능과 클라이언트 컴포넌트 지정 방법을 활용하여 하이드레이션 불일치를 방지하는 방법을 찾아야 했습니다.
코드
////////// 임포트
import dynamic from 'next/dynamic';
////////// 동작
// 동적으로 CalenderBlock 불러오기 (클라이언트 사이드에서만 렌더링)
const CalenderBlock = dynamic(() => import("../../templates/block/CalenderBlock"), {
ssr: false
});
////////// 렌더링
<CalenderBlock blockData={el.content} />
참고자료
https://nextjs.org/learn/seo/dynamic-import-components
SEO: Dynamic Imports for Components | Next.js
Dynamic Imports for Components Next, let's turn our attention to a React component that is not needed on the initial page load. React components can also be imported using dynamic imports, but in this case we use it in conjunction with next/dynamic to make
nextjs.org
'프론트엔드 > Next.js' 카테고리의 다른 글
Next.js에서의 CORS와 API 통신: 웹서버와 WAS의 공존 (0) | 2025.05.10 |
---|---|
[Next.js] Next.js + Typescript 환경에서 카카오 JS SDK 사용하기 (1) | 2025.05.08 |
[Next.js] <Image/> 태그 사용방법 (이미지 원본 비율 유지하기 & 부모 요소 너비 꽉 채우기) (0) | 2025.04.21 |
[Next.js] 파일 제출 버튼 스타일링 예시 코드 (0) | 2025.04.17 |
[Next.js] PWA 웹앱 구글 플레이 스토어 배포 방법 A to Z (1) | 2025.04.08 |