[ React ] 캘린더 컴포넌트 직접 만들기 (feat. date-fns)

2024. 6. 12. 13:02· React
목차
  1. 요구사항 분석
  2. 기능 구현 고민
  3. 구현
  4. 결과
728x90

요구사항 분석

  1. 오늘 날짜
  2. 이번 달 정보
    1. 시작하는 요일(1일)
    2. 몇 일까지 있는지
    3. 몇 주까지 있는지
  3. 이전 달, 다음 달 이동

 

기능 구현 고민

Date 객체를 더 쉽게 사용할 수 있게 도와주는 date-fns 라이브러리 함께 활용

  • 오늘 날짜 → new Date()
  • 시작하는 요일 → startOfMonth + getDay
  • 몇 일까지 있는지 → getDaysInMonth
  • 몇 주까지 있는지 → getWeeksInMonth
  • 다음 달 → addMonths
  • 이전 달 → subMonths

 

 


구현

1. 기준일 변수 생성

const [baseDate, setBaseDate] = useState(new Date());

달의 시작 요일, 일 수 등을 구하려면 기준일이 필요하다.

 

2. 요일 리스트

캘린더의 날짜 부분은 Grid로 구현할 것이기 떄문에 시작 요일 전까지 빈 값을 넣어줄 리스트가 필요하다.

 Array(firstDayOfMonth).fill(0);

getDaysInMonth로 구한 해당 달의 일 수를 map 함수로 그리드에 그려주려면 배열이 필요하다.

그러나 자바스크립트에는 파이썬의 range와 같은 간편한 함수가 없기 때문에 map 함수를 이용했다.

const newDate = [...Array(daysInMonth)].map((_, i) => {
  return i + 1;
});

 

⬇

<CalendarBody>
  {days.map((day) => (
    <CalendarEachDay>{day}</CalendarEachDay>
  ))}
  {blank.map(() => (
    <CalendarEachDay></CalendarEachDay>
  ))}
  {date.map((day) => (
    <CalendarEachDay>{day}</CalendarEachDay>
  ))}
</CalendarBody>

 

3. 함수화

const getMonthInfo = () => {
    const daysInMonth = getDaysInMonth(baseDate);
    const firstDayOfMonth = getDay(startOfMonth(baseDate)); // 0(일) ~ 6(토)
    const newBlank = Array(firstDayOfMonth).fill(0);
    setBlank(newBlank);
    const newDate = [...Array(daysInMonth)].map((_, i) => {
      return i + 1;
    });
    setDate(newDate);
};

달이 변경될 때마다 초기화해야 하는 시작 요일, 일 수, 요일 리스트를 구하는 함수를 하나로 묶어줬다.

 

4. 이전 달, 다음 달

<CalendarHeader>
  <MdOutlineNavigateBefore onClick={getPrev} />
  <span>{baseDate.getFullYear()}년 </span>
  <span>{baseDate.getMonth() + 1}월</span>
  <MdOutlineNavigateNext onClick={getNext} />
</CalendarHeader>
const getPrev = () => {
  setBaseDate(subMonths(baseDate, 1));
};
const getNext = () => {
  setBaseDate(addMonths(baseDate, 1));
};

subMonths, addMonths를 통해 새로운 기준일(baseDate)를 정해준다.

useEffect(() => {
  getMonthInfo();
}, [baseDate]);

기준일이 변경될 때마다 getMonthInfo 함수를 실행하여 달력 정보를 바꿔주도록 했다.

 

 


 

결과

 

728x90

'React' 카테고리의 다른 글

[ React ] weekSelector 컴포넌트 구현  (0) 2024.06.21
[ React ] useRef로 영역 외 클릭 시 감지 기능 구현하기  (0) 2024.06.19
[ React ] DatePicker 컴포넌트 직접 만들기  (0) 2024.06.17
[ React ] react-router-dom의 outlet으로 layout 구성하기  (0) 2024.06.13
[ React ] form에서 onChange 하나로 사용하기  (0) 2024.03.31
  1. 요구사항 분석
  2. 기능 구현 고민
  3. 구현
  4. 결과
'React' 카테고리의 다른 글
  • [ React ] useRef로 영역 외 클릭 시 감지 기능 구현하기
  • [ React ] DatePicker 컴포넌트 직접 만들기
  • [ React ] react-router-dom의 outlet으로 layout 구성하기
  • [ React ] form에서 onChange 하나로 사용하기
ZoD
ZoD
바쁘게 굴러가는 ZoD의 하루~
ZoD
como siempre
ZoD
  • 분류 전체보기 (173)
    • Daily (0)
    • Javascript (16)
      • 모던 자바스크립트 (46)
    • Typescript (8)
    • FrontEnd (7)
    • React (21)
      • tanstack query (1)
      • 라이브러리 (3)
    • Vue (33)
      • Nuxt (11)
      • Quasar (6)
    • CSS (12)
    • Storybook (8)
    • Figma (3)
    • CS 지식 (5)
    • Network (5)
    • 알고리즘 (2)
    • 사이드 프로젝트 (4)
      • ddangkong (4)
      • boncierge (0)
    • 개발, 근데 이제 헛소리를 곁들인 (1)
    • ETC (2)

블로그 메뉴

  • 홈
  • 태그
  • 방명록

인기 글

최근 글

hELLO · Designed By 정상우.v4.2.2
ZoD
[ React ] 캘린더 컴포넌트 직접 만들기 (feat. date-fns)
상단으로

티스토리툴바

단축키

내 블로그

내 블로그 - 관리자 홈 전환
Q
Q
새 글 쓰기
W
W

블로그 게시글

글 수정 (권한 있는 경우)
E
E
댓글 영역으로 이동
C
C

모든 영역

이 페이지의 URL 복사
S
S
맨 위로 이동
T
T
티스토리 홈 이동
H
H
단축키 안내
Shift + /
⇧ + /

* 단축키는 한글/영문 대소문자로 이용 가능하며, 티스토리 기본 도메인에서만 동작합니다.