한전 데이터 시각화 중, 선택한 날짜 또는 선택한 기간 동안의 전기사용량 데이터를 불러오는 기능을 추가하게 되었다. 내가 선택한 라이브러리는 React-Datepicker
이다. (react-date-picker
아님)
한전에 선택기간별 데이터를 보여주는 페이지가 있다. 이 기능을 그대로 가져오기 위해 react-datepicker 라이브러리를 선택했다.
설치 방법은 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 />}
/>
);
};
하나씩 디자인과 기능을 추가해주었다. 나는 기간 선택 기능을 넣고자 했기 때문에 두 개의 데이트피커를 연속해서 불러왔다.
<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])
변형을 해 주었다. startDate
와 endDate
를 분리해 state에 저장하게 했고 new Date()
로 가져온 현재 시간을 년-월-일 형태로 나타내기 위해 dateToString()
함수를 만들었다.
useEffect(() => {
setSearchDateString(dateToString(startDate))
setSelectedEndDateString(dateToString(endDate))
}, [startDate, endDate])
검색하고자 하는 날짜 문자열이 필요한 건 데이트피커 컴포넌트가 아니라 그 부모 컴포넌트인 전체 페이지에서 필요한 것이므로, props로 넘겨받은 setSearchDateString()
, setSelectedEndDateString()
함수를 useEffect
메서드를 활용해 원하는 시작/끝 날짜가 선택되는 즉시 부모 컴포넌트에서 setState
되도록 했다.
원하는 대로 잘 나왔음ㅋㅋㅋ
추카추카합니다