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 둘 다 호환이 가능합니다.

https://github.com/wix/react-native-calendars

 

 

 

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 날짜 선택기의 노브를 커스텀으로 렌더링하기 위한 함수

 

 

💡 [참고] 해당 라이브러리의 속성
 

Calendar | RNC

Calendar component

wix.github.io

 

 

 

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 };
}

 

 

 

 

 

 

오늘도 감사합니다. 😀

 

 

 

 

 

반응형