React에서 Dayjs로 캘린더 만들기

2020.12.31

dayjs calendar

React에서 Dayjs를 사용해 만든 캘린더

정기배송 프로젝트에서 고객이 원하는 배송일을 선택할 수 있는 달력을 만들었다.

다양한 캘린더 라이브러리가 있지만, 디자인이나 기능 커스텀에 한계가 있기 때문에 달력을 만들기로 결정했다.

momentjs로 만들다가 중단하고 dayjs로 처음부터 다시 만들면서 알게된 것들에 대한 기록이다.

여기를 클릭하면 프로젝트에 사용한 캘린더를 모듈화한 코드를 확인할 수 있다. 프로젝트에서는 redux를 통해 상태관리를 했는데, 모듈화 코드에는 어디서나 사용할 수 있도록 redux 부분을 삭제했다.

dayjs vs momentjs

momentjs는 date 라이브러리 중 가장 오래되고 보편적으로 사용되는 라이브러리다. API를 폭넓게 지원하여 편리하지만 용량이 크다는 단점을 가지고 있다.

momentjs와 비슷한 기능을 지원하지만 용량이 작은 dayjs를 사용하면 momentjs의 편의성은 살리고 단점을 커버할 수 있다. dayjs를 사용하면 momentjs 대비 약 97% 작은 용량을 사용할 수 있다.

2018년에 출시된 dayjs가 momentjs의 자리를 대신하고 있는 추세다.

공식 사이트 링크

How to use Dayjs

dayjs를 설치한다.

$ npm install dayjs --save
$ yarn add dayjs

리액트 파일에서는 아래와 같이 import해주면 된다.

import dayjs from 'dayjs'

  //day
  const dayjs = require('dayjs');

💪🏻 immutable

객체의 상태를 업데이트 하는 momentjs과 달리 dayjs은 immutable해 별로도 clone를 하지 않아도 된다. 기존 momentjs 코드를 dayjs로 변경할 때 가장 신경써야 하는 부분이다.

import moment from 'moment'
import dayjs from 'dayjs'

const momentDate = moment('2020-12-30');
momentDate.add(1, 'day'); //momentDate의 상태가 변경된다.
console.log(momentDate.format('YYYY-MM-DD')); // '2020-12-31'

const dayjsDate = dayjs('2020-12-30');
dayjsDate.add(1, 'day'); //dayjsDate의 상태는 변경되지 않는다.
console.log(dayjsDate.format('YYYY-MM-DD')) // '2020-12-30'

//add 한 상태를 보고 싶다면 이렇게 사용 해야 한다.
console.log(dayjsDate.add(1, 'day').format('YYYY-MM-DD')) // '2020-12-31'

const dayjsAddDate = dayjsDate.add(1, 'day');
console.log(dayjsAddDate.format('YYYY-MM-DD')) //'2020-12-31'

📦 extend

dayjs는 Plugins을 사용해 필요한 기능들만 extend 할 수 있도록 설계되어 있다. dayjs가 momentjs에 비해 엄청나게 작은 용량으로 비슷한 기능을 지원할 수 있는 것이 바로 이 덕분이다.

공식사이트의 Plugins를 참고해 필요한 기능을 추가하면 된다. 언어는 i18n을 참고해 같은 방식으로 추가하면 된다.

import dayjs from 'dayjs'

  //day
  const dayjs = require('dayjs');
  const weekday = require('dayjs/plugin/weekday');
  const isoWeek = require('dayjs/plugin/isoWeek');
  const weekOfYear = require('dayjs/plugin/weekOfYear');

  // day extend
  dayjs.extend(weekday);
  dayjs.extend(isoWeek);
  dayjs.extend(weekOfYear);
© Copyright 2020 marveloper All rights reserved.