Gila - Minified React error #425

박상준·2024년 9월 5일

Gila

목록 보기
20/25

버그다 버그

분명 로컬 환경에서는 아무런 이상이 없었는데 배포하고 확인해보니 에러가 발생한다.

모든 페이지에서 발생하는 문제는 아니고 디테일 페이지에서만 발생하는 문제다. 기능에 심각한 문제를 초래하는 버그는 아니지만 아무래도 에러는 에러이기 때문에 해결해야 했다.

무슨 에러일까

위의 에러 메세지에서 전체 메세지를 확인해 보라고 해서 react 페이지에서 error 메세지를 확인해봤다.

간단하게 얘기해서 서버에서 렌더링된 HTML과 현재 브라우저에 렌더링된 HTML이 일치하지 않다는 것이다. 현재 디테일 페이지는 대부분의 데이터를 서버에서 미리 받아서 서버 렌더링을 거치고 있다. 그래서 페이지를 새로고침하면서 어떤 부분이 문제가 있나 확인해봤다.

문제를 찾다보니 새로고침시에 기간 부분이 깜빡이는 것을 확인할 수 있다. 여기 때문에 그런 에러가 발생하는 것이다.

이런 현상이 발생하는 이유

그럼 이게 왜 이렇게 될까? 우선 해당 데이터는 Date 형식으로 들어가 있는 것을 date-fns로 format을 적용해서 해당 컴포넌트에 넣어놨다. 그래서 시간의 오류때문이라고 생각했다. 그래서 우선적으로는 vercel 서버의 위치가 미국으로 되어 있어서 그런가라고 생각했다.

그래서 vercel의 funtion region의 위치를 미국에서 서울로 바꿔주었다. 그러면 될까 싶었지만 결국 이 문제는 해결되지 않았다.

그렇다면 문제는 date-fns에서 발생하는 것이였다. 그래서 구글링을 통해 date-fns의 timezone이 어떻게 설정되어 있는지 확인을 했다.

다행히 누군가 timezone에 대한 질문을 남겼고 그에 대한 답변도 확인할 수 있었다. 이 문제는 date-fns의 문제가 아니고 ECMAScript의 Date 생성 설정때문이라고 되어있었다.
그래서 Date에 대해서 조금 찾아보니

시간대가 UTC기준으로 되어있다는 것을 확인했다.

그렇다면 에러가 발생하는 이유를 생각해보자면 date-fns에서는 Date를 통해 날짜를 변환하는데 Date의 시간대 기준이 UTC기준이였다. 그러다보니 한국시간과 UTC시간대의 차이가 발생하고 그래서 서버에서 렌더링 하는 시점에서는 UTC, 클라이언트에서 렌더링하는 시점에서는 한국 시간대로 설정되어서 시간사이에 간극이 발생하는 것이다.

해결 방법

가장 쉬운 해결 방법은 리액트방식대로 해결하는 것이다. 이런 변화에 대응하려면 state값으로 지정해 useEffect와 같은 훅으로 처리해버리면 되긴한다. 하지만 해당 로직을 많은 곳에서 사용하고 있고 사실상 하드코딩으로 해결하기엔 너무 불필요하다. 게다가 우리는 해외 서비스를 지원하지 않아서 시간대를 한국으로 설정해주기만 하면 되는 문제였다.

그래서 다음 대안으로 date-fns에서 제안한 date-fns-tz라는 라이브러리를 사용하기로 했다. 기존에 사용하던 format()에서 timezone이 설정가능해 진다.

npm i date-fns-tz

간단하게 설치해준 이후

import { formatInTimeZone } from 'date-fns-tz';

const formatDateRange = ({
  startDateString,
  endDateString,
}: {
  startDateString: Date;
  endDateString: Date;
}) => {
  const formattedStartDate = formatInTimeZone(startDateString, 'Asia/Seoul', 'yyyy.MM.dd');
  const formattedEndDate = formatInTimeZone(endDateString, 'Asia/Seoul', 'yyyy.MM.dd');

  return `${formattedStartDate} ~ ${formattedEndDate}`;
};

이렇게 fotmatInTimeZone이라는 것을 사용해서 변환시켜주면 된다. 전과 다르게 중간에 timezone을 넣어주면 된다. 우리는 Asia/Seoul로 넣어줬다.

결과

바로 배포까지 적용시켜서 확인해봤을때

아까 발생했던 에러도 발생하지 않고 깜빡이는 현상도 발생하지 않는다.

마무리

사소한 에러였지만 그래도 해결이 되어서 다행이다. 하나씩 문제를 해결할수록 조금씩 배우는 느낌이 들어서 좋다. 물론 이것도 스스로 해결한 문제까지는 아니라고 생각이 든다. 하지만 처음부터 배부를수는 없으니 천천히 해보면 되는 것이다.

다음 포스트는 메일과 관련된 기능을 넣어볼 예정이다. 현재 여러 사용자 상호작용이 있는데 그걸 알려줄수 있는 매개체가 없다. 그래서 내가 생각한 것은 에어비엔비처럼 예약에 관한 내용을 메일로 보내주는 것이다. 그러면 실제 약속 사이트처럼 구성이 갖춰질 것 같다.

이 기능을 구현하기 위해 메일도 실제 유효한 메일인지 확인하는 결과를 거쳐야 하기 때문에 메일 인증까지 같이 구현해보겠다.

profile
개인 블로그 플렛폼도 운영중입니다(https://blog-park.vercel.app/)

0개의 댓글