s e o p p o r t . l o g

Today I Learned

[클룸] react-day-picker 사용기

Seo Ji Won 2024. 4. 19. 20:35

원래의 기획은 클래스를 한달마다 해당 월에만 등록될 수 있도록 했다.

++ 이전 글 참고

https://seopport-u.tistory.com/75

그런데 문제가 발생했다.

이 클래스는 4월 26일과 5월 2일에 예약이 가능한데,

내가 짰던 로직은 1부터 31일까지의 배열을 만들고, DB의 활성화 날짜의 day만 가져와서

그 day를 뺀 배열을 daypicker의 disable 속성에 배열로 전달해주었기 때문에

5월 2일이 아니라 4월 2일에 예약이 가능하다고 나오게되는 문제가 있었다.

 

그래서 이걸 어떻게해야할지 생각해봤지만 애초에 클래스를 등록할 때 다른 달의 날짜도 자유롭게 등록할 수 있는 것이 맞는것 같아서 기획을 수정하게 되었다.

따라서 달마다 비활성화 날짜 배열을 만들어서 할당해주어야 했다. 이걸 어떻게 달마다 관리를 해야할지 생각을 해보았다. day-picker에 활성화 날짜 속성이 있었다면 바로 해결이 가능했지만 아무리 찾아봐도 없었다.

그래서 생각해본 방법은

 

1. before, after 사용하기

disable 속성에 before, after를 지정할 수 있다.

예를 들어

before: new Date(), after: ['2024-04-28']

이런식으로 전달하면 오늘 기준으로 과거의 날짜와 4월 28일의 날짜는 모두 비활성화 된다. 

따라서 before을 오늘 날짜로, after를 클래스의 마지막 예약 가능일로 설정하면 그 전후로는 모두 disable이 될 거고,

그러면 그 사이의 날짜 range를 date_fns 등등을 사용해서 배열로 만들어서

그 배열과 활성화 날짜를 비교해서 비활성화 날짜배열을 만들어 보는 방식..을 생각해보았다.

 

해결방법 - disable에 콜백함수 사용하기

활성화 날짜만 넣어주는 부분은 분명 다른 사람들도 많이 사용할 로직일텐데 방법이 없을리가 없다고 생각했고

스택오버플로우를 싹다 뒤져보니.. 방법이 있었다

알고보니 데이피커의 disable 속성에 기본적으로 모든 날짜의 day 배열이 제공이 되고 있었다.

따라서 disabled 속성에 day로 콜백함수를 돌려서 내가 가지고 있는 날짜배열만 제외되도록 하면 되는 것이었다.🤤

그런데 일치하는 날짜가 있는데도 모든 날짜가 일치하지 않는다고 나오는 오류가 있었다. 콘솔을 찍어보니 

데이피커에서 제공하고 있는 day는 00시인데, 내가 db에서 가져온 날짜는 09시로 시작하고 있었다.

그 이유는 DB에는 시간대 없이 2024-03-09 이런식으로 날짜만 저장하고 있었기 때문에

내가 DB에서 날짜를 가져와서 new Date()로 날짜 형식으로 포맷했을 때 한국시간 기준인 09시로 초기화되기 때문이었다.

DB에서 받아온 형식을 바꾸는것보다는 데이피커의 day를 DB과 같은 형식으로 포맷해서 비교하도록 했다.

 include 메서드로 전체 day에서 DB에서 받아온 날짜 배열을 제외한 배열을 전달하도록 했다.

다음은 전체 코드이다

  const availableDays = classDates.map((dateInfo) => dateInfo.day);
  // ['2024-03-02', '2024-03-28']


<DayPicker
    mode="single"
    required
    selected={new Date(selectedDate)}
    onSelect={handleDateChange}
    disabled={(day) => !availableDays.includes(format(day, 'yyyy-MM-dd'))}
    locale={ko}
    fromYear={new Date().getFullYear()}
    toYear={new Date().getFullYear() + 1}
    components={{
      Caption: CustomCaption
    }}
/>

 

주말 반납할 각오로 하려했는데 1시간만에 해결됨..🤤