[Next.js] SSR Error (React18 error #423, #418, #425)

찐새·2022년 10월 24일
0

next.js

목록 보기
40/41
post-thumbnail

개인 블로그 사이트의 블로그게시판 페이지를 SSR로 변경하는 작업을 하면서 발생한 에러 기록이다.

23.04.23 수정
다시 해당 discussion에 들어가 살펴보니 useEffect를 사용하지 않고 해결하는 방법이 있어 수정한다.

해결 방법을 공유한 글를 보면, time태그에 suppressHydrationWarning를 추가했다.

suppressHydrationWarningSSR에서 서버와 클라이언트가 서로 다른 것을 렌더링할 때 발생하는 경고다. 이것을 true로 설정하면 내용의 불일치에 대해 경고하지 않는다. 다만, React docs - suppressHydrationWarningReact 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>
  );
}
profile
프론트엔드 개발자가 되고 싶다

1개의 댓글

comment-user-thumbnail
2023년 1월 14일

캬.. 날짜를 위해서 매번 useEffect 써야하는게 너무 가혹한데요..

답글 달기