원하는 날짜의 한 달짜리 달력을 제작해보았다. (기본값 내 생일)
- 빈 배열 생성 : 날짜들을 넣을 빈 배열을 만든다.
- 이전 달 공백 생성 : 이번 달의 시작 요일(0일~6토)을 구하고 그만큼 빈 컴포넌트를 위의 배열에 삽입한다. 수요일이라면 3개 만큼의 빈 컴포넌트를 넣게된다.
- 이번 달 생성 : 이번 달의 마지막 날짜를 구하고, 1일부터 마지막 날짜까지 반복문을 통해 각각의 날짜 정보가 담긴 컴포넌트를 위의 배열에 삽입한다.
- 다음 달 공백 생성 : 총 42개의 칸(7일*6줄)에서 2번과 3번의 갯수만큼 제외하고 남은 숫자만큼 빈 컴포넌트를 위의 배열에 삽입한다.
const Calendar = (day: Dayjs) => {
const allDays = []
for (let index = 0; index < day.startOf("month").day(); index++) {
allDays.push(<S.DayBlock></S.DayBlock>)
}
new Array(Number(day.endOf("month").format("DD")))
.fill(1)
.map((dayNumber, index) => {
const eachDay = dayjs(`${day.year()}-${day.month() + 1}-${dayNumber + index}`)
allDays.push(<S.DayBlock key={dayNumber + index}>{eachDay.date()}</S.DayBlock>)
})
for (let index = 0; index < 42 - day.endOf("month").date() - day.startOf("month").day(); index++) {
allDays.push(<S.DayBlock></S.DayBlock>)
}
return allDays
}
날짜 : dayjs로 생성한 날짜. (dayjs()는 지금 시간을 반환)
날짜.startOf("month") : 날짜에 해당하는 달의 시작일에 대한 날짜를 반환.
날짜.day() : 요일을 숫자(0일~6토)로 반환. ( year() / month() / date()도 마찬가지)
날짜.format("DD") : 날짜의 일(date)을 문자로 반환.
기본적인 바닐라 js도 이정도 기능은 가지고 있지만, 앞으로 사용하게 될 기능의 사용을 위하여 날짜 관련 기능은 라이브러리로 통일하기로 하였고, 공식문서를 보고 적용하였다.
처음에 달력의 구조에 대해 몰랐을 때에는, 달력의 컴포넌트를 어떤 방법으로 생성을 시작해야할 지 막막했었는데, 기준이 되는 날짜의 달을 먼저 구하고, 거기에서부터 앞 뒤로 뻗어나가는 방법으로 달력의 구조를 이해하게 되었다.
처음 테스트 당시엔 36500개의 모든 달력을 전부 나타내려 했지만, 지금은 내가 보고 있는 화면 안에서만 컴포넌트가 렌더되어도 동일한 효과를 나타낼 수 있게되었다. (앞으로 무한 스크롤 등을 통해 컴포넌트를 마운트하고, 지나간 컴포넌트를 마운트 해제하는 등.)