어드민 프로젝트이다보니 날짜, 시간 포멧팅 사용이 많아 date-fns를 사용하였다.
로컬 작업시에는 찍히지 않던 에러가 배포하고나니 초기 렌더링 시에 와장창 뜨는것이 아닌가...
에러도 종류별로 나는것같아 보여서 에러 내의 리액트 링크를 타고 들어갔더니
Text content does not match server-rendered HTML.
Hydration failed because the server rendered HTML didn't match the client. As a result this tree will be regenerated on the client. This can happen if a SSR-ed Client Component used:
- A server/client branch
if (typeof window !== 'undefined')
.- Variable input such as
Date.now()
orMath.random()
which changes each time it's called.- Date formatting in a user's locale which doesn't match the server.
- External changing data without sending a snapshot of it along with the HTML.
- Invalid HTML tag nesting.
It can also happen if the client has a browser extension installed which messes with the HTML before React loaded.
There was an error while hydrating but React was able to recover by instead client rendering the entire root.
이러한 내용들이었다.
서버에서 렌더링 한 내용과 클라이언트에서 렌더링 한 내용이 맞지 않아서 생긴 문제인가싶어 코드를 다 찾아봤지만 다르게 렌더링 될 만한 부분이 보이지 않는데 ..?
페이지와 컴포넌트 단위로 가려가며 배포 해서 확인해보기로 하였더니 날짜를 쓰던 곳을 가렸을 때에는 에러가 나지않는것을 확인!
다시 검색을 두드려본 결과 이와 동일한 문제의 이슈내용이 있었다.
date-fns의 문제인가싶어 getDate() 처럼 직접 뜯어서 포멧팅을 해보았지만, 동일한 에러가 나는것을 보고 Date 객체 자체가 문제가 있는것 같다는것을 직감하였다...
다시 코멘트를 하나하나 읽고 내 문제일까 싶은것을 찾던 중 발견한 글!
서버의 Data 객체는 기본적으로 UTC 기준
브라우저는 자동으로 현지 시간으로 변환
UTC != KST 가 되어버린 것이다.
그렇다면 KST로 고정을 해주면 되지않을까?
date-fns에서 타임존을 셋팅해주려면 "date-fns-tz"를 확장 아리브러리를 추가로 install 해줘야 한다.
export const KST = "Asia/Seoul";
const zonedDate = toZonedTime(date, KST);
format(zonedDate, "yyyy.MM.dd", { timeZone: KST })
KST를 사용한 Date로 바꿔주고, 이 타임존을 사용해서 포멧팅 해줘! 라고 이중으로 알려줘야한다.
이렇게 싹 바꿔준 이후 배포 시 에러 없이 깔-끔
리액트 에러내용처럼 Date와 random 같이 환경이나 실행 시점에 따라 다르게 보여질 수 있는부분은 미리 인지를 할 수 있어야 할 것 같다.
로컬에서 잘된다고 방심 노노!
공부하며 정리&기록하는 ._. 씅로그