요즘 공부 목적으로 겸사겸사 하는 프로젝트가 있는데, 날짜와 시간을 선택하는 그럴 듯한 컴포넌트가 필요했다. 감사하게도 npm 모듈 중에 이를 사용하기 쉽도록 만들어 놓은 (커스텀도 매우 간단!) 것이 있어 해당 모듈을 사용하며 뭔가 정리하고 싶어져서 글을 쓴다.


기본적인 사용법

공식문서 코드를 따라 치면

import React, { useState } from "react";
import DatePicker from "react-datepicker";
import "react-datepicker/dist/react-datepicker.css";

const Example = () => {
  const [startDate, setStartDate] = useState(new Date());
  return (
    <DatePicker 
    	selected={startDate}
	onChange={(date) => setStartDate(date)} 
    />
  );
};

공식 문서에 나와있는 코드이다. 이렇게 하고 해당 컴포넌트를 렌더링해주면 위 캡처화면에서와 같이 기본적인 datepicker 틀을 만나볼 수 있다. 나는 이제 이 기본 틀을 커스텀 하려고 한다.

datepicker 커스텀 하기

커스텀하기 위해서는 시간을 다루는 함수를 많이 사용해야 하는데, 우선 date-fns 모듈도 다운 받아주자. 커스텀할 때 유용하게 쓰인다.

컴포넌트 수정하기


위에서의 Example 컴토넌트를 위와 같이 수정해보자. 캘린더의 글씨와 날짜는 한글로 표시되며 날짜가 출력되는 형태도 바뀐다. 그리고 화살표를 제거하였고 오늘 날짜보다 이전 날짜는 선택하지 못하게 한다. 마지막으로 날짜가 뜨는 인풋 박스도 예쁘게 커스텀한다.

import React, { useState } from "react";
import DatePicker from "react-datepicker";
import "react-datepicker/dist/react-datepicker.css";
import Form from "react-bootstrap/Form";
import { ko } from "date-fns/esm/locale";

const Example = () => {
  const [startDate, setStartDate] = useState(new Date());
  return (
    <DatePicker
    	selected={startDate} 
	onChange={(date) => setStartDate(date)}
        locale={ko}                   // 한글로 변경
        dateFormat="yyyy.MM.dd (eee)" // 시간 포맷 변경
        showPopperArrow={false}       // 화살표 변경
        minDate={new Date()}          // 오늘 날짜 전은 선택 못하게
        customInput={		      // 날짜 뜨는 인풋 커스텀
          <Form.Control as="textarea" rows={1} style={{width:"250px"}}/>
	}
    />
  );
};

CSS 수정하기


날짜가 선택됐을 때 모양과 색깔을 바꾸고 싶다면 CSS를 수정해주면 된다. 그런데 나의 경우 이 방법을 사용하면 살짝 버벅거렸는데 끝내 이유를 끝내 알아내지 못해 CSS에서 important!를 사용했다. (important!는 최대한 남발하지 말도록 하자 ㅠㅠ)

아래 코드를 보면 알 수 있듯이 선택한 날짜의 월과 일과, 달력에서의 월과 일이 같다면 해당 day의 calssName을 selected-day로 해주는 코드이다.

import React, { useState } from "react";
import DatePicker from "react-datepicker";
import "react-datepicker/dist/react-datepicker.css";
import Form from "react-bootstrap/Form";
import { ko } from "date-fns/esm/locale";
import { getMonth, getDate } from "date-fns";
import "./day.css"

const Example = () => {
  const [startDate, setStartDate] = useState(new Date());
  return (
    <DatePicker
    	selected={startDate} 
	onChange={(date) => setStartDate(date)}
        locale={ko}                   // 한글로 변경
        dateFormat="yyyy.MM.dd (eee)" // 시간 포맷 변경
        showPopperArrow={false}       // 화살표 변경
        minDate={new Date()}          // 오늘 날짜 전은 선택 못하게
        customInput={		      // 날짜 뜨는 인풋 커스텀
          <Form.Control as="textarea" rows={1} style={{width:"250px"}}/>
	}
        dayClassName={(d) =>
            getDate(d) === getDate(startDate) && getMonth(d) === getMonth(startDate)
                ? 'normal-day selected-day'
                : 'normal-day'
        }
    />
  );
};
.normal-day {
    background: white !important;
    color: black !important;
    width: 28px;
    height: 28px;
    line-height: 1.8;
    text-align: center;
    padding: 2px !important;
}

.selected-day {
    background: navy !important;
    color: white !important;
    border-radius: 50% !important;
    font-weight: 700;
}

선택된 날짜 부모로 넘기기

나는 모임의 제목과 날짜를 정해서 등록하는 기능을 만들고 있었다. 그럼 모임 form 컴포넌트는 (부모 컴포넌트) datepicker 컴포넌트를 (자식 컴포넌트) 감싸고 있다. 따라서 선택된 날짜를 자식 컴포넌트에서 부모 컴포넌트로 넘겨줘야 했다.

Object형을 String으로 변환


그런데 선택된 날짜를 부모에게 바로 넘겨주니 이런 오류를 만날 수 있었다. 😒 그니까 이제 Object는 React에서 자식이 될 수 없다는 거다. 그렇다. datepicker로 선택된 날짜의 타입은 Object이다.

따라서 난 아래와 같이 String으로 변환해주어서 부모 컴포넌트로 전달해주었다. 이때 또 아까 썼던 date-fns 모듈이 유용하게 쓰인다.

import { getMonth, getDate, getDay } from "date-fns";

function seletTime() {
    let Days = ['일', '월', '화', '수', '목', '금', '토'];
    let Month = getMonth(startDate) + 1;
    let Date = getDate(startDate);
    let Day = Days[getDay(startDate)];
    // 오브젝트는 전달 안돼서 string으로 변환
    props.setClubTime(String(Month + "." + Date + " (" + Day + ")"))
}

레퍼런스

profile
유키링と 욘데 쿠다사이

0개의 댓글

관련 채용 정보

Powered by GraphCDN, the GraphQL CDN