Date Picker 직접 구현 해보기!

Taesol Kwon·2020년 6월 7일
0

1. 갑자기 웬 Date Picker???

그렇다. 갑자기 이걸 왜 구현해야하는가? 과제라 그렇다. 덕분에 라이브러리로만 쓰던 Date Picker를 직접 구현해보다니...ㅎㅎ
한번 구현해 봤으니 다음부터는 라이브러리로 써야겠다. 머리 터지는줄;;

2. 어떻게 구현할까?

일단 들어가기 앞서 두 가지 선택권이 있다.
1번: 자바스크립트의 Date 객체를 사용하는 방법
2번: moment.js(Date 객체를 좀 더 쉽게 활용할 수 있게 하는 일차원적인 라이브러리)를 사용하는 방법

나는 1번을 시도하다가 2번으로 돌아섰다. 시간이 없었다 ;;
일단 일반적인 달력을 만드는 것을 목표로 하자.

2-1. 필요한 것

  • 한 달 일자 수
  • 달의 시작이 어느 날인지

이 두가지만 있으면 만사 오케이다!! 는 아니고 짱구좀 굴려야함 ㅋㅋ

2-2. 개발시작

나는 간단히 어떤 방향으로 작업하면 되는지만 보여줄 것이다.

import React, {useState} from "react"
import moment from "moment";

const Days = () => {
  const [date, setDate] = useState(moment()) //오늘 날짜가 들어옴!
  const thisDate = moment(date);
  const daysInMonth = moment(date).daysInMonth();
  const firstDayDate = moment(date).startOf("month");
  const previousMonth = moment(date).subtract(1, "month"); //지난달의 오늘 일자
  const previousMonthDays = previousMonth.daysInMonth(); //지난달의 총 일수
  const nextMonth = moment(date).add(1, "month");

  let labels = [];
  let days = [];

  //요일 만들기 (월,화,수,목,금,토,일)
  for (let i = 1; i <= 7; i++) {
    const dayOfWeek = moment().day(i).format("dd");
    labels.push(
      <span className="label" key={i}>
        {dayOfWeek}
      </span>
    );
  }

  //이번 달 1일 앞에 들어갈 지난 달 마지막 날짜 생성
  for (let i = firstDayDate.day(); i > 1; i--) {
    previousMonth.date(previousMonthDays - i + 2);

    days.push(
      <span key={moment(previousMonth).format("DD MM YYYY")}>
        {date.date()}
      </span>
    );
  }

  //이번 달 1~31일자 생성
  for (let i = 1; i <= daysInMonth; i++) {
    thisDate.date(i);

    days.push(
      <span key={moment(thisDate).format("DD MM YYYY")}>
        {date.date()}
      </span>
    );
  }

  // daysCnt는 현재 달력에서 보이는 이전달의 마지막 날짜들부터 이번달 일자들 총합
  // baseNum은 본인이 조절하고 싶은대로 조절하면 되는데, 마지막 날 이후 들어갈 다음달 초기 날짜 개수를 정할 수 있다.
  const daysCnt = days.length;
  let baseNum;
  if (daysCnt > 35) {
    baseNum = 42;
  } else {
    baseNum = 35;
  }
  //이번 달 마지막 날 이후 들어갈 다음달 초기 날짜 생성
  for (let i = 1; i <= baseNum - daysCnt; i++) {
    nextMonth.date(i);

    days.push(
      <span key={moment(nextMonth).format("DD MM YYYY")}>
        {date.date()}
      </span>
    );
  }

  return (
    <nav className="dp-days">
      <div className="label-wrapper">{labels}</div>
      <div className="days-wrapper">{days.concat()}</div>
    </nav>
  );
};

export default Days;

이렇게 하면 작성일자 기준으로 6월달의 달력이 완성되어 지는것을 볼 수 있을 것이다.
이전 달이나 다음달의 달력을 얻으려면 setDate()를 이용해 달을 업데이트해줘야하는데 고민해보시고!
정 모르겠다!? 나는 답을 원한다 싶으면 편하게 라이브러리 쓰면 된다. ㅋㅋㅋ

** 추가로 range 기능은 너무 길어질까봐 이곳에 쓰지 않았다.
추후에 깃헙 레포를 참조해 놓겠다.

profile
사진촬영을 좋아하는 프론트엔드 개발자입니다.

0개의 댓글