반응형
- 요구 사항들이 다 정리가 되었기에 우선 이 날짜 기능을 어떻게 구현할지를 정해야 했다.
- 직접 구현할 것인지 아니면 라이브러리를 쓸 것 인지
- 전에 패x에서 달력을 바닐라 자바스크립트로 만드는 강의를 본 기억이 있었지만
- 그 강의는 단순히 달력기능까지만 나왔으며
- 이번에는 복잡하게 날짜 데이터들을 가공해야하며
- 무엇보다 시간제한이 걸려있기에(없었다면 바닐라 자바스크립트로 했었을 것 같다.. 실력향상에도 좋고 확장성도 좋고)
- 라이브러리를 선택하기로 했다.
- 라이브러리는 크게 react-calendar 와 react-datepicker가 있었는데 나는
- react-datepicker의 레퍼런스 코드가 어느정도 있음
- 공식사이트의 설명이 직관적임
- 의 이유로 react-datepicker를 사용하기로 결정했다.
순서대로 구현해보자.
- 막상 만들때는 페이지네이션도 써야 했기에 조금 해맸었지만 여기서는 날짜 관련만 이야기 해보고자 한다.
- 우선 게시판에 크게 이벤트를 등록할 수 있어야 한다.
- 그리고 이 이벤트에는 시작날짜, 시작시간, 끝시간 이렇게 3개의 input이 주어지고
- 1개는 클릭하면 달력이
- 2개는 시간이 나와야한다.
- 처음에 날짜를 오늘로 했다면 처음 시간 input에는 현재시간 이전은 선택하면 안된다.
- 시작시간을 정하기전에는 끝시간을 정할 수 없으며 시작시간이 정해지면 그 시간 이전시간들은 비활성화 된다.
datepicker 기본 사용법 및 스타일링
- 우선은 import부터 시작하자면
import DatePicker from "react-datepicker";
import "react-datepicker/dist/react-datepicker.css";
import "../../../elements/DatePicker.css";
- 이렇게 총 3개를 import 해오는 데 차례대로
- datepicker
- datepickre 기본 css
- datepicker 커스텀 css 이다.
- 3번째의 커스텀 css는
.react-datepicker__input-container input {
width: 82px;
height: 19px;
padding: 5px 10px;
background: #f5f5f5;
border: 1px solid white;
border-radius: 5px;
font-size: 15px;
font-weight: 400;
text-align: center;
color: #2b2b2b;
}
.react-datepicker {
font-size: 1.3rem !important;
}
.react-datepicker__current-month {
font-size: 1.5rem !important;
}
.react-datepicker__header {
padding-top: 6px !important;
}
.react-datepicker__day-name, .react-datepicker__day {
margin: 0.5rem !important;
}
.saturday {
color: rgb(0, 0, 255) !important;
}
.sunday {
color: rgb(255, 0, 0) !important;
}
.react-datepicker__day--disabled {
color: #cccccc !important;
}
.react-datepicker-wrapper {
width: unset;
/* margin-right: 16px; */
}
.react-datepicker__day--selected, .react-datepicker__day--in-selecting-range, .react-datepicker__day--in-range,
.react-datepicker__month-text--selected,
.react-datepicker__month-text--in-selecting-range,
.react-datepicker__month-text--in-range,
.react-datepicker__quarter-text--selected,
.react-datepicker__quarter-text--in-selecting-range,
.react-datepicker__quarter-text--in-range,
.react-datepicker__year-text--selected,
.react-datepicker__year-text--in-selecting-range,
.react-datepicker__year-text--in-range {
background-color: black;
}
.react-datepicker__day--keyboard-selected,
.react-datepicker__month-text--keyboard-selected,
.react-datepicker__quarter-text--keyboard-selected,
.react-datepicker__year-text--keyboard-selected {
background-color: black;
}
.react-datepicker__header {
background-color: unset;
border: none;
}
.react-datepicker__month-container {
padding: 0.5rem;
}
.react-datepicker__day-names {
color: #6b6b6b;
font-weight: 500;
}
.react-datepicker__day--outside-month {
color: #6b6b6b;
}
.react-datepicker__tab-loop {
background-color: royalblue;
position: absolute;
}
- 이런식으로 원래 있던 datepicker의 클래스를 이용해 스타일링을 하는 방식이다.(사실 나도 아직 완벽히는 모른다..)
- https://reactdatepicker.com/
- 내가 공식문서를 사용한 형식은 우선 default를 따라가고 필요한 기능이 있을때 마다 공식문서를 참고하여 적용하는 방식이었다.
- 사실 이렇게 라이브러리와 공식문서를 본격적으로 사용하는 게 처음이라 공식문서를 잘 활용하지 못하고 구글링으로 스택오버플로우를 많이 참고했었다.
- 그리고는 정말 무수히도 많이 해메었다.
- 과거에 공부를 할 때 꼭 공식문서를 제일 먼저 보라고 귀에 피가 나도록 들었지만 또 잘 지키지 못한 셈이다.
- 후반에 들어서야 많은 삽질 끝에 공식문서를 참고하기 시작했는데 disabled같은 간단하지만 매우매우 유용했던 기능이나 customInput같은 살짝은 복잡한 기능도 사용할 수 있게 되었다.
- 라이브러리를 사용할 때 막힌다면 공식문서를 먼저 찾아보는 것이 좋다라는 것을 깨달았고 응용이 중요하다는 것을 알았다.
- 나의 완성형 코드는 다음과 같았다.
<DatePicker
className={
startDateTrim && !startDate ? "trimError date" : "date"
}
placeholderText="YYYY.MM.DD"
selected={startDate}
onChange={setStartDate}
showPopperArrow={false}
locale={ko} // 한글로 변경
dateFormat="yyyy.MM.dd" // 시간 포맷 변경
autoComplete="off"
selectsStart
minDate={new Date()}
endDate={endDate}
startDate={startDate}
ref={startDateRef}
onBlur={onBlurStartDateCheck}
customInput={<ExampleCustomInput />}
/>
- 이 코드가 나오기 까지 많은 시행착오가 있었는데
- 우선 className같은 경우 나는 저렇게 className이라는 속성안에 삼항 연산자를 쓴 것이 아닌 밖에다가 썼다.
- 즉, 원래는
<DatePickerBox>
{startDateTrim && !startDate ? (
<ErrorDatePicker>
<DatePicker
className="trimError"
placeholderText="YYYY.MM.DD"
selected={startDate}
onChange={setStartDate}
showPopperArrow={false}
locale={ko} // 한글로 변경
dateFormat="yyyy.MM.dd" // 시간 포맷 변경
autoComplete="off"
selectsStart
minDate={new Date()}
endDate={endDate}
startDate={startDate}
ref={startDateRef}
onBlur={onBlurStartDateCheck}
customInput={<ExampleCustomInput />}
// style={{ border: "2px solid #ff0000" }}
/>
</ErrorDatePicker>
) : (
<DatePicker
placeholderText="YYYY.MM.DD"
selected={startDate}
onChange={setStartDate}
showPopperArrow={false}
locale={ko} // 한글로 변경
dateFormat="yyyy.MM.dd" // 시간 포맷 변경
autoComplete="off"
selectsStart
minDate={new Date()}
endDate={endDate}
startDate={startDate}
ref={startDateRef}
onBlur={onBlurStartDateCheck}
customInput={<ExampleCustomInput />}
/>
)}
</DatePickerBox>
- 이런 느낌이었다..
- 여기서도 다시 느껴지는게 나는 이번 기능을 구현하면서 삼항연산자를 잘 쓰지 못해 많은 삽질을 했고 또 삼항연산자로 많은 난관을 구현했으며 그래서 삼항 연산자를 전보다는 조금 다룰 수 있게 된 것 같아.
- 기능을 배움에 있어 알고만 있고 쓰지 못하면 그건 알고 있는게 아니다라는 생각을 절실히 하게 되었다.
- (사실 여기서의 리팩토링은 내가 한게 아니라 내 선임분이 했다..)
- 하나하나 뜯어보자면
- placeholderText는 말그대로 선택하기 전에 적혀있는 힌트문구 이고
- selected는 선택하면 나오는 날짜이다.
- 즉, onChange에 있는 setStartDate를 통해 startDate를 지정하게 되고 이게 반영되는 것이다.
- dateFormat은 시간 포멧을 변경하는것이다. (지금 적으면서 본거지만 이걸 잘 활용해서 진행했다면 후반에 date 객체의 포멧때문에 삽질하는 시간을 줄일 수 있지 않았을까 싶다..)
- minDate, startDate, endDate는 각각
- 과거를 선택하지 못하게 할때 과거의 기준
- 달력에서 범위를 지정할 때 시작점
- 달력에서 범위를 지정할 때 끝점 이다.
- 이벤트를 등록할때는 당일만 등록하도록 기획이 되어 있기에 지금은 endDate를 알 수가 없지만 흔히들 경험한 비행기 왕복 날짜를 정할때 그 범위가 시작 날짜에도 보이게 해주는 그 기능이다.
- ref는 useRef를 이용해서 datepicker를 가공할 수 있도록 도와주는데 나의 경우는 만들기만 하고 쓰지는 않았다
- onBlur는 과거 회원가입을 만들때 유용 했던 그 기능으로 입력하지 않고 넘어갔을 때 에러메시지를 띄우게 하는 것 이지만 여기서는 쓰이지 않았다.
- 그리고 중요했던 속성이 하나 있는데 바로 customInput과 그 안의 forwardRef이다.
- customInput속성은 하나의 컴포넌트를 그 값으로 받는데
- 속성의 이름과 같이 input창을 커스텀 할 수 있게 된다.
- 이때 forwardRef가 쓰이게 되는데 자세한 forwardRef에 대한 자세한 내용은
- https://www.daleseo.com/react-forward-ref/
- 여기가 잘 설명했으니 참고하고
- datepicker에서는 customInput 안에 쓰이는 값에 value와 onClick이 이미 정의되어 있기 때문에
const ExampleCustomInput = forwardRef(({ value, onClick }, ref) => ( <DateButton onClick={onClick} ref={ref} color={value.length === 0 ? "#b3b3b3" : "black"} > {value.length === 0 ? "YYYY.MM.DD" : value} </DateButton> )); ///// const DateButton = styled.div` width: 384px; border-radius: 10px; border: 2px solid #e4e4e4; background-color: #ffffff; padding-left: 20px; height: 36px; font-family: "Noto Sans KR"; font-style: normal; font-weight: 300; font-size: 16px; line-height: 36px; letter-spacing: -0.04em; /* color: black; */ color: ${props => props.color}; `;
- 나는 이런식으로 응용했다.
- 이렇게 하면 손쉽게 datepicker의 input창을 custom할 수 있다.
- 참고로 color는 value의 length를 이용해서 placeholder를 구현했다.
- 이제보니까 엉망이다.. 위에서의 placeholderText를 지워도 이 코드 때문에 전혀 문제 되지 않는다.
- 당연하다면 당연한게 이 customInput을 통해 위의 placeholderText가 덮어지기 때문이다.
반응형
'develop' 카테고리의 다른 글
날짜 기능이 있는 게시판 만들기 with datepicker (4) - 이벤트 등록시 (0) | 2023.02.25 |
---|---|
날짜 기능이 있는 게시판 만들기 with datepicker (3) - 응용에서 겪은 문제 (1) | 2023.02.23 |
날짜 기능이 있는 게시판 만들기 with datepicker (1) - 요구사항 (0) | 2023.02.21 |
AWS 하나의 도메인으로 두 개의 웹사이트 호스팅하기 - SubDomain (0) | 2023.01.25 |
CloudFront로 S3에 HTTPS적용하기 with ACM 인증서 (0) | 2023.01.25 |