[React] React Datepicker 라이브러리 사용법

이은진·2021년 1월 25일
15

1. React-Datepicker 사용 계기

한전 데이터 시각화 중, 선택한 날짜 또는 선택한 기간 동안의 전기사용량 데이터를 불러오는 기능을 추가하게 되었다. 내가 선택한 라이브러리는 React-Datepicker 이다. (react-date-picker 아님)

한전에 선택기간별 데이터를 보여주는 페이지가 있다. 이 기능을 그대로 가져오기 위해 react-datepicker 라이브러리를 선택했다.

2. 설치 방법

설치 방법은 npm에 잘 나와 있고, https://www.npmjs.com/package/react-datepicker

공식 웹사이트는 이렇게 생겼다. https://reactdatepicker.com

먼저 설치를 해 준다.

npm install react-datepicker --save

package.json 파일을 열어 잘 설치됐는지 확인한다.

"react-datepicker": "^3.4.1",

원하는 파일에서 import해준다.

import DatePicker from "react-datepicker";

그리고 공식 사이트를 켜 놓고 작업을 시작한다. 참고로 이 react datepicker 라이브러리는 커스텀이 깡패라 웬만한 기능은 다 가져다 붙일 수 있다. 나는 내가 원하는 모양으로 버튼을 만들고 싶었기 때문에 이 코드를 복붙했다.

const DatePickerComponent = () => {
  const [startDate, setStartDate] = useState(new Date());
  const ExampleCustomInput = ({ value, onClick }) => (
    <button className="example-custom-input" onClick={onClick}>
      {value}
    </button>
  );
  return (
    <DatePicker
      selected={startDate}
      onChange={date => setStartDate(date)}
      customInput={<ExampleCustomInput />}
    />
  );
};

3. 커스텀하기

하나씩 디자인과 기능을 추가해주었다. 나는 기간 선택 기능을 넣고자 했기 때문에 두 개의 데이트피커를 연속해서 불러왔다.

  <div className={classes.startDateContainer}>
    <DatePicker
      selected={startDate}
      selectsStart
      maxDate={new Date()}
      customInput={<CustomInput />}
    />
  </div>
  {
    isRangeSearch && (
      <React.Fragment>
        <div className={classes.range} />
        <div className={classes.endDateContainer}>
          <DatePicker
            selected={endDate}
            selectsEnd
            startDate={startDate}
            minDate={startDate}
            maxDate={new Date()}
            customInput={<CustomInput />}
          />
        </div>
      </React.Fragment>
    )
  }

데이트피커 컴포넌트가 필요한 페이지도 있고, 그렇지 않은 페이지도 있는 데다가, 어떤 페이지는 원하는 날짜만 선택하면 되는 반면에 어떤 페이지는 두 날짜를 선택해야 하는 페이지도 있었기 때문에, isRangeSearch 라는 props 를 부모에서 넘겨주어 기간선택의 경우 끝나는 날짜를 선택하는 컴포넌트도 렌더되도록 했다.

const DatePickerComponent = ({ setSearchDateString, setSelectedEndDateString, isRangeSearch }) => {
  const classes = useStyles();
  const [startDate, setStartDate] = useState(new Date());
  const [endDate, setEndDate] = useState(new Date())
  const [isCalendarOpen, setIsCalendarOpen] = useState(false)

  const dateToString = (date) => {
    return date.getFullYear() + '-' + (date.getMonth() + 1).toString().padStart(2, '0') + '-' + date.getDate().toString().padStart(2, '0')
  }

  const CustomInput = ({ value, onClick }) => (
    <div className={classes.datePickerButton} onClick={onClick}>
      {value}
      {
        isCalendarOpen ? <ArrowDropUpIcon /> : <ArrowDropDownIcon />
      }
    </div>
  );

  useEffect(() => {
    setSearchDateString(dateToString(startDate))
    setSelectedEndDateString(dateToString(endDate))
  }, [startDate, endDate])

변형을 해 주었다. startDateendDate를 분리해 state에 저장하게 했고 new Date()로 가져온 현재 시간을 년-월-일 형태로 나타내기 위해 dateToString() 함수를 만들었다.

  useEffect(() => {
    setSearchDateString(dateToString(startDate))
    setSelectedEndDateString(dateToString(endDate))
  }, [startDate, endDate])

검색하고자 하는 날짜 문자열이 필요한 건 데이트피커 컴포넌트가 아니라 그 부모 컴포넌트인 전체 페이지에서 필요한 것이므로, props로 넘겨받은 setSearchDateString(), setSelectedEndDateString() 함수를 useEffect 메서드를 활용해 원하는 시작/끝 날짜가 선택되는 즉시 부모 컴포넌트에서 setState 되도록 했다.

원하는 대로 잘 나왔음ㅋㅋㅋ

profile
빵굽는 프론트엔드 개발자

4개의 댓글

comment-user-thumbnail
2021년 1월 27일

추카추카합니다

1개의 답글
comment-user-thumbnail
2021년 4월 12일

안녕하세요. 따라서 작성해보고있는데요, 어디서 실수했는지를 모르겠네요...ㅠ
혹시 전체 소스 공유 부탁드려도 될까요??

답글 달기
comment-user-thumbnail
2021년 9월 16일

ㅋㅋㅋ 레지나 여기서 보게되네요 요즘 리액트로 개발하고 있는데 반갑네요 by george

답글 달기