개인 블로그 사이트의 블로그
와 게시판
페이지를 SSR
로 변경하는 작업을 하면서 발생한 에러 기록이다.
23.04.23 수정
다시 해당discussion
에 들어가 살펴보니useEffect
를 사용하지 않고 해결하는 방법이 있어 수정한다.
해결 방법을 공유한 글를 보면, time
태그에 suppressHydrationWarning
를 추가했다.
suppressHydrationWarning
은 SSR
에서 서버와 클라이언트가 서로 다른 것을 렌더링할 때 발생하는 경고다. 이것을 true
로 설정하면 내용의 불일치에 대해 경고하지 않는다. 다만, React docs - suppressHydrationWarning과 React docs - hydrateRoot()에서는 마크업의 개수가 많으면 성능상의 불이익을 가져올 수 있으니 남용하지 말 것을 권고하고 있다.
export default function TimeComponent(timeData:string) {
return (
<time dateTime={timeData} suppressHydrationWarning>
{timeData}
</time>
);
}
로컬에서는 문제없이 잘 돌아갔는데, vercel
에 배포한 후 아래와 같은 에러 메시지를 받았다.
Uncaught Error: Minified React error #425; visit https://reactjs.org/docs/error-decoder.html?invariant=425 for the full message or use the non-minified dev environment for full errors and additional helpful warnings.
Uncaught Error: Minified React error #418; visit https://reactjs.org/docs/error-decoder.html?invariant=418 for the full message or use the non-minified dev environment for full errors and additional helpful warnings.
Uncaught Error: Minified React error #423; visit https://reactjs.org/docs/error-decoder.html?invariant=423 for the full message or use the non-minified dev environment for full errors and additional helpful warnings.
안내된 링크를 열어 보니 SSR
단계에서 뭔가 일어난 듯했다.
after updating react 18, i have problems with date-fns #37489
next.js
깃허브 이슈에 해당 에러를 검색해 보니 토론되고 있던 이슈가 있었다. 원인은 new Date
했을 때 클라이언트의 시간과 서버의 시간이 맞지 않기 때문이라고 한다. 또한, Next.js
의 에러가 아닌 React18
이슈여서, 해당 이슈는 Discussion으로 넘어갔다.
먼저 시간을 나타내는 컴포넌트를 <Suspense>
로 감싸 봤지만, #418
에러만 해결될 뿐, 나머지 둘은 그대로였다.
그 다음은 토론에서 제시한 방법을 사용했다. useEffect
를 사용하여 클라이언트에서 강제로 렌더링 되게끔 조정하는 것이다.
export default function TimeComponent({ timeData }) {
const [date, setDate] = useState<Date>();
useEffect(() => {
if (timeData && window) {
const date = new Date(timeData);
setDate(date);
}
}, [regDate]);
return (
<div>
{ date ?
<span>{`${("0" +(date?.getMonth() + 1))}-${date?.getDate()}`}</span>
:
<span>Loading...</span>
}
</div>
);
}
캬.. 날짜를 위해서 매번 useEffect 써야하는게 너무 가혹한데요..