React & React Native/라이브러리 활용
[RN] react-native calendars 이해하고 활용하기
adjh54
2023. 11. 16. 18:07
반응형
반응형
해당 글에서는 react-native-calendars에 대해 이해하고 응용하는 다양한 예시를 알아봅니다.
1) react-native-calendars
💡 react-native-calendars
- 리액트 네이티브 애플리케이션에서 캘린더 기능을 구현하기 위한 패키지입니다. 해당 패키지는 Android 및 iOS 둘 다 호환이 가능합니다.
1. 설치 과정
💡 패키지 매니저인 npm이나 yarn을 이용하여 설치하여 주시면 됩니다.
$ npm install --save react-native-calendars
# or
$ yarn add react-native-calendars
2. Calendar 속성
속성 | 설명 |
onDayPress | 날짜를 선택했을 때 호출되는 콜백 함수 |
markedDates | 특정 날짜에 대한 표시 및 스타일 지정을 위한 객체 |
firstDay | 캘린더의 시작날짜를 정합니다. firstDay = 1인 경우 월요일부터 한주가 시작됩니다 |
minDate | 선택할 수 있는 최소 날짜 |
maxDate | 선택할 수 있는 최대 날짜 |
disabledDates | 선택할 수 없는 날짜들을 배열로 지정 |
monthFormat | 월 텍스트의 형식 |
theme | 캘린더 컴포넌트의 테마를 지정하는 객체 |
renderHeader | 캘린더 헤더를 커스텀으로 렌더링하기 위한 함수 |
renderArrow | 좌우 화살표를 커스텀으로 렌더링하기 위한 함수 |
renderDay | 날짜 셀을 커스텀으로 렌더링하기 위한 함수 |
renderEmptyDate | 비어있는 날짜 셀을 커스텀으로 렌더링하기 위한 함수 |
renderKnob | 날짜 선택기의 노브를 커스텀으로 렌더링하기 위한 함수 |
💡 [참고] 해당 라이브러리의 속성
3. Calendar 예시
💡 일일 Calendar 사용 예시입니다.
/**
* 날짜 형식 변경 (YYYY-MM-DD)
*/
const cvtParamDate = (date: Date): string => {
const year = date.getFullYear();
const month = String(date.getMonth() + 1).padStart(2, '0');
const day = String(date.getDate()).padStart(2, '0');
return `${year}-${month}-${day}`;
}
/**
* 선택한 날짜를 State에 저장합니다.
*/
const onChange = (selectedDate) => {
const currentDate = new Date(selectedDate.dateString) || new Date();
setIsDailyReportOpen(Platform.OS === 'ios');
setChoiceDate(currentDate);
},
<Calendar
firstDay={1}
monthFormat={'yyyy년 MM월'}
current={cvtParamDate(choiceDate)}
maxDate={cvtParamDate(new Date())} // 내일은 선택하지 못하도록 구성
onDayPress={(day) => onChange(day)}
disableTouchEvent={true}
theme={{
backgroundColor: '#ffffff',
calendarBackground: '#ffffff',
selectedDayTextColor: '#6491ff',
selectedDayBackgroundColor: '#eef6ff',
todayTextColor: '#ffffff',
todayBackgroundColor: '#6491ff',
dayTextColor: '#616d82',
textDisabledColor: '#d9e1e8',
arrowColor: 'orange',
textDayFontFamily: 'monospace',
textMonthFontFamily: 'monospace',
textDayHeaderFontFamily: 'monospace',
textDayFontWeight: '300',
textMonthFontWeight: 'bold',
}}
/>
💡주간 Calendar 사용 예시입니다
/**
* 날짜 형식 변경 (YYYY-MM-DD)
*/
const cvtParamDate = (date: Date): string => {
const year = date.getFullYear();
const month = String(date.getMonth() + 1).padStart(2, '0');
const day = String(date.getDate()).padStart(2, '0');
return `${year}-${month}-${day}`;
}
/**
* 선택하는 날짜를 State에 저장합니다.
* @param selectedDate
*/
const onChange = (selectedDate) => {
const currentDate = new Date(selectedDate.dateString) || new Date();
setIsDailyReportOpen(Platform.OS === 'ios');
setChoiceDate(currentDate);
};
<Calendar
firstDay={1}
monthFormat={'yyyy MM월'}
maxDate={cvtParamDate(lastWeekSunday)}
current={cvtParamDate(choiceWeek)}
onDayPress={(day => onChange(day))}
theme={{
selectedDayBackgroundColor: 'blue',
arrowColor: 'blue',
dotColor: 'green',
todayTextColor: 'yellow',
backgroundColor: 'white'
}}
/>
2) react-native-calendars 응용하기 -1 : 공통
1. 날짜 타입을 문자열로 변환 방법
💡 해당 부분에서는 파라미터로 전달받은 날짜 타입을 문자열로 변환하는 방법에 대해 알아봅니다.
1. cvtDateToString: Date → 0000년 0월 0일 (요일)
2. cvtDateToString2: Date → 0000년 00월 00일 (요일)
3. cvtDateToString3: Date → 00년 00월 00일(요일)
4. cvtDateToString4 → 0000-00-00
/**
* 날짜 타입을 문자열로 변환합니다 : 0000년 0월 0일 (요일)
* @param date
* @returns
*/
const cvtDateToString = (date: Date): string => {
const year = date.getFullYear();
const month = date.getMonth() + 1;
const day = date.getDate();
const dayOfWeek = ["일", "월", "화", "수", "목", "금", "토"][date.getDay()];
return `${year}년 ${month}월 ${day}일 (${dayOfWeek})`; // 2023년 1월 1일(일)
}
/**
* 날짜 타입을 문자열로 변환합니다 : 0000년 00월 00일 (요일)
* @param date
*/
const cvtDateToString2 = (date: Date): string => {
const year = date.getFullYear();
const month = String(date.getMonth() + 1).padStart(2, '0');
const day = String(date.getDate()).padStart(2, '0');
const dayOfWeek = ["일", "월", "화", "수", "목", "금", "토"][date.getDay()];
return `${year}년 ${month}월 ${day}일 (${dayOfWeek})`; // 2023년 11월 16일 (목)
}
/**
* 날짜 타입을 문자열로 변환합니다 : 00년 00월 00일 (요일)
* @param date
*/
const cvtDateToString3 = (date: Date): string => {
const year = String(date.getFullYear()).slice(-2);
const month = String(date.getMonth() + 1).padStart(2, '0');
const day = String(date.getDate()).padStart(2, '0');
const dayOfWeek = ["일", "월", "화", "수", "목", "금", "토"][date.getDay()];
return `${year}년 ${month}월 ${day}일 (${dayOfWeek})`; // 23년 11월 16일 (목)
}
/**
* 날짜 타입을 문자열로 변환합니다 : 2023-11-16
* @param date
* @returns
*/
const cvtDateToString4 = (date: Date): string => {
const year = date.getFullYear();
const month = String(date.getMonth() + 1).padStart(2, '0');
const day = String(date.getDate()).padStart(2, '0');
return `${year}-${month}-${day}`; // 2023-11-16
}
2. 문자열을 날짜 타입으로 변환 방법
💡 문자열을 날짜 타입으로 변환
- 0000-00-00 형태의 문자열을 Date 타입으로 변환합니다.
/**
* 문자열을 날짜 타입으로 변환합니다
* @param str
* @returns
*/
const cvtStringToDate = (str: string): Date => {
const dateString = '2023-11-16';
return new Date(dateString);
}
3. 날짜 타입 연산 방법
💡 날짜 타입 연산
- 파라미터로 전달받은 날짜와 연산되는 숫자를 전달받아서 날짜를 더하고 뺍니다.
/**
* 파라미터 날짜(date) 기준으로 값을 연산(perNum)합니다.
* @param date
* @param perNum
* @returns
*/
const cvtDateCalc = (date: Date, perNum: number) => {
const year = date.getFullYear();
const month = date.getMonth();
const calcDate = date.getDate() + perNum;
const newDate = new Date(year, month, calcDate);
return newDate;
}
3) react-native-calendars 응용하기 -2 : 일일 캘린더
1. 하루 전, 다음 날 이동 방법
💡 하루 전, 다음 날 이동
- 파라미터로 type을 받습니다. prev일 경우면 전날, post일 경우 다음날의 값을 반환받는 함수를 구성하였습니다.
/**
* 파라미터 날짜(date) 기준으로 값을 연산(perNum)합니다.
* @param date
* @param perNum
* @returns
*/
const cvtDateCalc = (date: Date, perNum: number) => {
const year = date.getFullYear();
const month = date.getMonth();
const calcDate = date.getDate() + perNum;
const newDate = new Date(year, month, calcDate);
return newDate;
}
/**
* 선택한 날짜와 타입에 따라서 전날, 다음날의 값을 반환합니다.
* @param date
* @param type
* @returns
*/
const moveDailyDate = (date: Date, type: "prev" | "post"): Date => {
let resultDate = new Date()
if (type === "prev") resultDate = calcDate(date, -1);
else if (type === "post") resultDate = calcDate(date, +1);
return resultDate
}
2. 하루 전, 다음 날 이동 + 이동제한하기 방법
💡 하루 전, 다음 날 이동 + 이동제한하기
/**
* 선택한 날짜와 타입에 따라서 전날, 다음날로 이동합니다. (단, 오늘 이후에 대해 이동을 못하도록 막습니다.)
* @param date
* @param type
* @returns
*/
const moveDailyDate2 = (date: Date, type: "prev" | "post"): Date => {
let resultDate = new Date()
if (type === "prev") resultDate = calcDate(date, -1);
else if (type === "post") {
// 만약에 늘렸을 경우 내일인 경우 움직이지 않도록 한다.
const tomorrow = calcDate(new Date(), +1); // 실제 내일
const nextDate = calcDate(date, +1); // 다음 선택한날
// [CASE1] 내일을 선택한 경우
if (tomorrow.getFullYear() === nextDate.getFullYear()
&& tomorrow.getMonth() === nextDate.getMonth()
&& tomorrow.getDate() === nextDate.getDate()) {
setToastMsgInfo({ isShowToast: true, message: "내일을 선택 할 수 없습니다.", type: "daily" })
}
// [CASE2] 내일이 아닌 경우를 선택한 경우
else {
resultDate = calcDate(date, +1);
}
}
return resultDate
}
4) react-native-calendars 응용하기 -2 : 주간 캘린더
1. 한 주 반환받는 방법
/**
* 이번주 파라미터 날짜 기준 월요일과 일요일을 구합니다.
* @param date
*/
const cvtDatetoWeekStr = (date: Date): { weekStart: Date, weekEnd: Date } => {
// 월요일
const weekStart = new Date(date);
weekStart.setDate(date.getDate() - date.getDay() + 1);
// 일요일
const weekEnd = new Date(date);
weekEnd.setDate(date.getDate() - date.getDay() + 7);
return { weekStart, weekEnd }
}
2. 한 달의 주차를 반환받는 방법
/**
* 날짜 타입을 기반으로 오늘이 한달의 몇 주차 인지 반환받는 함수
* @param date
* @returns
*/
const getWeekNumber = (date: Date) => {
const firstDayOfMonth = new Date(date.getFullYear(), date.getMonth(), 1);
const firstDayOfWeek = firstDayOfMonth.getDay();
const offset = firstDayOfWeek > 0 ? 7 - firstDayOfWeek : 0;
const dayOfMonth = date.getDate();
return `${Math.ceil((dayOfMonth + offset) / 7)} 주차`;
}
3. 전주, 다음주 이동 방법
/**
* 날짜 타입을 기준으로 타입을 지정하여 전달하면 전주, 다음주의 값을 반환받습니다.
* @param date
* @param type
* @returns
*/
const moveWeek = (date: Date, type: "prev" | "post") => {
let currentDate = new Date(date);
if (type === "prev") {
currentDate.setDate(currentDate.getDate() - ((currentDate.getDay() + 6) % 7));
} else if (type === "post") {
currentDate.setDate(currentDate.getDate() + (7 - currentDate.getDay()));
}
let startDate = new Date(currentDate);
let endDate = new Date(currentDate);
endDate.setDate(endDate.getDate() + 6);
return { startDate: startDate, endDate: endDate };
}
오늘도 감사합니다. 😀
반응형