1. 완성 모습
2. 작성 코드
import React, { useState } from 'react';
function Calendar() {
// 기준이 되는 오늘 날짜를 date에 담아준다
const [date, setDate] = useState(new Date());
// 오늘의 날짜를 기준으로 년, 월, 일 만들기
const year = date.getFullYear();
const month = date.getMonth();
const firstDay = new Date(year, month, 1);
// 마지막 일은 매달 다르므로 다음달의 0일로 지정
// new Date(2023, 3 + 1, 0); => Sun Apr 30 2023 00:00:00 GMT+0900 (한국 표준시)
const lastDay = new Date(year, month + 1, 0);
// 길이가 마지막 일인 배열을 생성하고 인덱스+1을 해줘서 1~마지막일까진 들어있는 배열 만든다
const days = [...Array(lastDay.getDate()).keys()].map((i) => i + 1);
// 달 변경 시 기준 날짜 변경해는 함수
const prevMonth = () => setDate(new Date(year, month - 1, 1));
const nextMonth = () => setDate(new Date(year, month + 1, 1));
return (
<div className="calendar">
<div className="month">
<button onClick={prevMonth}>{'<'}</button>
{/* 월 표시 형식 지정 */}
{firstDay.toLocaleString('default', { month: 'long' })}
<button onClick={nextMonth}>{'>'}</button>
</div>
<div className="weekdays">
<div>Sun</div>
<div>Mon</div>
<div>Tue</div>
<div>Wed</div>
<div>Thu</div>
<div>Fri</div>
<div>Sat</div>
</div>
<div className="days">
{/* 첫주 공백 getDay()은 해당 날이 무슨 요일인지 숫자로 알 수 있음*/}
{[...Array(firstDay.getDay()).keys()].map((i) => (
<div key={`empty-${i}`} className="day empty" />
))}
{/* 1일부터 마지막 일*/}
{days.map((day) => (
<div key={day} className="day">
{day}
</div>
))}
{/* 마지막주 공백 */}
{[...Array(6 - lastDay.getDay()).keys()].map((i) => (
<div key={`empty-${i}`} className="day empty" />
))}
</div>
</div>
);
}
export default Calendar;
.calendar {
padding: 10px;
margin: 20px auto 20px auto;
}
.month {
display: flex;
justify-content: space-between;
align-items: center;
font-size: 24px;
margin-bottom: 10px;
font-weight: 700;
color: #393e46;
}
.weekdays {
/* 그리드를 통해 7칸씩 나누어준다 */
display: grid;
grid-template-columns: repeat(7, 1fr);
font-size: 14px;
font-weight: bold;
text-align: center;
margin-bottom: 10px;
color: #393e46;
}
.weekdays :first-child {
color: #00adb5;
}
.weekdays :last-child {
color: #03c2cc;
}
.days {
display: grid;
/* 그리드를 통해 7칸씩 나누어준다 */
grid-template-columns: repeat(7, 1fr);
gap: 10px;
color: #393e46;
}
.day {
display: flex;
justify-content: center;
align-items: center;
width: 40px;
height: 40px;
border-radius: 50%;
}
/* 토요일의 날짜 색상 변경 */
.day:nth-of-type(7n) {
color: #03c2cc;
}
/* 일요일의 날짜 색상 변경 */
.day:nth-of-type(7n + 1) {
color: #00adb5;
}
.empty {
visibility: hidden;
}
button {
background-color: var(--gra1);
color: var(--bl-color);
font-weight: 800;
border: none;
border-radius: 3px;
cursor: pointer;
}
3. 사용한 메서드 정리
3-1. 날짜 관련 메서드
new Date()
- Date 객체를 생성해 주며, 현재 날짜와 시간을 가져 올 수 도 있고 특정 날짜로 생성할 수도 있다.
const currentDate = new Date();
console.log(currentDate);
// Mon Apr 10 2023 16:03:39 GMT+0900 (한국 표준시)
const specificDate = new Date('2022-05-01T10:30:00');
console.log(specificDate);
// Sun May 01 2022 10:30:00 GMT+0900 (한국 표준시)
getFullYear(), getMonth(), getDate()
- 날짜의 연도, 월, 일을 가져올 수 있다.
const currentDate = new Date(); // 2023년 4월 10일일 경우
const currentYear = currentDate.getFullYear();
console.log(currentYear);
// 2023
const currenMonth = currentDate.getMonth();
console.log(currenMonth);
// 4
const currenDate = currentDate.getDate();
console.log(currenDate);
// 10
getDay()
날짜의 요일을 가져올 수 있다.
일요일은 0, 월요일은 1, ..., 토요일은 6으로 표현된다.
const currentDate = new Date();
const currentDay = currentDate.getDay();
console.log(currentDay);
// 1
toLocaleString()
로컬 시간대에 맞추어 날짜와 시간을 문자열로 변환한다.
const event = new Date(Date.UTC(2012, 11, 20, 3, 0, 0));
console.log(event.toLocaleString('en-GB', { timeZone: 'UTC' }));
// "20/12/2012, 03:00:00"
console.log(event.toLocaleString('ko-KR', { timeZone: 'UTC' }));
// "2012. 12. 20. 오전 3:00:00"
3-2. 배열 관련 메서드
Array()
Array 객체를 생성할 때 사용한다.
`new Array(arrayLength)`
arr.keys()
배열의 각 인덱스를 키 값으로 가지는 새로운 객체를 반환한다.
const array1 = ['a', 'b', 'c'];
const iterator = array1.keys();
for (const key of iterator) {
console.log(key);
}
// 0
// 1
// 2
마치며..
Date관련된 메서드가 엄청 다양하던데 처음 알았다. 그리고 그리드 사용 어렵던데 그리드 제너레이터 사용하면 좀더 쉽게 만들 수 있다.
참고
mdn
'React' 카테고리의 다른 글
Redux Thunk 미들웨어 사용해보기 (0) | 2023.04.11 |
---|---|
to do 앱 만들기 후기 (0) | 2023.04.09 |
Proxy (0) | 2023.04.04 |
Custom Hook (0) | 2023.03.27 |