yarn add react-datepicker date-fns
yarn add -D @types/react-datepicker
import React, { useState } from 'react';
import ReactDatePicker from 'react-datepicker';
import 'react-datepicker/dist/react-datepicker.css';
export const Calendar = () => {
const [startDate, setStartDate] = useState<Date | null>(new Date());
return (
<div>
<ReactDatePicker
selected={startDate}
onChange={(date) => setStartDate(date)}
/>
</div>
);
};
css파일을 import해줘야만 달력이 제대로 나오는 것을 확인할 수 있다.
사용자가 오늘 날짜 이후부터만 선택할 수 있도록 minDate 속성을
통해 오늘 날짜로 설정하면 된다.
<ReactDatePicker
selected={startDate}
minDate={new Date()}
onChange={(date) => setStartDate(date)}
/>
달력을 예약 시스템에서 사용되고 있어 예약된 날짜가 있으면
선택하지 못하게 제외된 날짜로 설정해줘야 한다.
excludeDateIntervals 속성을 통해 제외시키고 싶은 날짜를
시작 범위와 끝 범위를 입력한다.
시작 범위도 제외하고 싶다면 subDays를 통해 하루를 빼줘야
시작 범위를 포함해 제거된다.
import ReactDatePicker, { registerLocale } from 'react-datepicker';
import { subDays } from 'date-fns';
import ko from 'date-fns/locale/ko';
import 'react-datepicker/dist/react-datepicker.css';
registerLocale('ko', ko);
interface Props {
onDatesChange: (dates: [Date, Date], nights: number) => void;
}
export const Calendar = ({ onDatesChange }: Props) => {
useEffect(() => {
getCampAreaReservation(id!).then((res) => setExcludeDates(res));
}, []);
const onChange = (dates: [Date, Date]) => {
onDatesChange(dates, nights);
const [start, end] = dates;
setStartDate(start);
setEndDate(end);
};
return (
<div>
<ReactDatePicker
dateFormat='yyyy-MM-dd'
selected={startDate}
minDate={new Date()}
startDate={startDate}
endDate={endDate}
selectsRange
onChange={onChange}
excludeDateIntervals={excludeDates?.map((exclude) => ({
start: subDays(new Date(exclude.check_in_date), 1),
end: new Date(exclude.check_out_date),
}))}
locale='ko'
showIcon
icon={svg}
/>
</div>
);
};
[참고한 사이트]
https://bloghelloworld.tistory.com/330
https://react-hook-form.com/docs/usecontroller/controller
https://reactdatepicker.com/#example-calendar-icon
https://beomy.github.io/tech/react/react-hook-form/
https://react-hook-form.com/docs/usecontroller/controller
https://doooodle932.tistory.com/150