'Minified React error'를 해결했습니다
들어가며
제 블로그에 불필요한 로그가 남아있는지 확인하기 위해 브라우저 콘솔을 열어보았더니, 다음과 같은 에러를 발견했습니다.
보통은 에러가 어디서 발생했는지 알 수 있지만, 이 에러는 어디서 발생했는지 알 수 없었습니다. 먼저 이 에러에 대한 설명이 있는 React 공식 문서를 확인해보기로 했습니다.
- Minified React error #418: 서버에서 렌더링된 HTML이 클라이언트와 일치하지 않아 Hydration에 실패했습니다. 결과적으로 이 트리는 클라이언트에서 다시 생성됩니다.
- Minified React error #423: Hydration 중에 오류가 발생했지만 React는 대신 전체 루트를 클라이언트에서 렌더링하여 복구할 수 있었습니다.
- Minified React error #425: 텍스트 내용이 서버에서 렌더링된 HTML과 일치하지 않습니다.
이 에러를 읽어보면, 'Hydration'과 관련된 에러라고 판단할 수 있습니다. 그렇다면, 'Hydration'이란 무엇일까요?
'Hydration'이란?
'Hydration'은 일반적으로 '수분 보충'을 의미하지만, React 공식 문서에서는 이렇게 설명하고 있습니다.
In React, “hydration” is how React “attaches” to existing HTML that was already rendered by React in a server environment. During hydration, React will attempt to attach event listeners to the existing markup and take over rendering the app on the client.
— React
React에서 "hydration"은 서버 환경에서 React로 이미 렌더링된 기존 HTML에 React가 "연결"하는 방법입니다. hydration 중에 React는 기존 마크업에 이벤트 리스너를 연결하고 클라이언트에서 앱의 렌더링을 담당합니다.
— React
간단히 설명하자면, 서버 측에서 클라이언트 측으로 물을 공급하듯이, 서버에서 렌더링된 HTML에 React를 연결하는 것을 'Hydration'이라고 합니다. 이 'Hydration' 중에 에러가 발생하면 React는 클라이언트 측에서 전체 루트를 렌더링합니다.
어디서 에러가 발생했는가?
인터넷을 찾아보니, 이 에러가 발생하는 원인은 서버 측 시간과 클라이언트 측 시간이 다른 경우에 주로 발생하는 것 같습니다. 서버 측 시간은 UTC 시간이고, 클라이언트 측 시간은 로컬 시간인 것이 원인 중 하나로 꼽혔습니다.
저는 이 블로그를 6개월 전에 만들었고, 최근에 리팩토링을 시작하면서 제 블로그의 메인 페이지에 게시일을 표시한 것을 깜빡 잊고 있었습니다. 그래서 어떤 컴포넌트에서 에러가 발생하는지 알 수 없었습니다. 하나씩 컴포넌트를 지우면서 에러가 발생하는 컴포넌트를 특정했습니다.
문제가 발생한 컴포넌트는 다음 코드였습니다.
<div className="text-center w-full">
<p className="text-sm dark:text-neutral-300">
{new Date(post.date).toLocaleDateString()}
</p>
<h3 className="font-semibold dark:text-neutral-100 truncate mx-5">
{post.title}
</h3>
</div>
에러 해결 방법
이 부분을 다음과 같이 수정하여 에러를 해결할 수 있었습니다.
- {new Date(post.date).toLocaleDateString()}
+ {new Date(post.date).toISOString().split("T")[0]}
이렇게 하여 서버 측과 클라이언트 측의 시간을 일치시켜 에러를 해결할 수 있었습니다.
마치며
다른 에러는 어디서 발생하는지 알 수 있지만, 이 에러는 어디서 발생하는지 알 수 없었습니다. 앞으로 저와 같은 에러를 겪을 분들을 위해 이 에러에 대해 설명해 보았습니다. 다음에는 더 좋은 글로 찾아뵙겠습니다.