마지막 구성할 화면은 달력화면 입니다.
react-native-calendars라는 라이브러리를 사용합니다.
$ yarn add react-native-calencars
components/CalendarView.js
import React from 'react';
import {StyleSheet} from 'react-native';
import {Calendar} from 'react-native-calendars/src/index';
function CalendarView() {
return <Calendar style={styles.calendar} />;
}
const styles = StyleSheet.create({
calendar: {
borderBottomWidth: 1,
borderBottomColor: '#e0e0e0',
},
});
export default CalendarView;
screens/CalendarScreen.js
import React from 'react';
import CalendarView from '../components/CaendarView';
function CalendarScreen() {
return <CalendarView />;
}
export default CalendarScreen;
이제 달력 탭으로 가면 달력이 보이나요?
달력에 표시하기
지금은 달력에 아무런 표시도 없습니다.
앞으로 사용자가 달력에서 특정 날짜를 선택해 해당 날짜에 작성된 로그를 조회하는 기능을 구현할 것입니다.
이 기능을 구현하기 위해서는 사용자가 현재 선택한 날짜, 로그를 작성한 날짜에 특별한 표시를 해주겠습니다.
추가로 달력에 사용되는 색상들도 변경하겠습니다.
components/CalendarView.js
import React from 'react';
import {StyleSheet} from 'react-native';
import {Calendar} from 'react-native-calendars/src/index';
function CalendarView() {
const markedDates = {
'2023-03-25': {
selected: true,
},
'2023-03-26': {
selected: true,
},
'2023-03-27': {
selected: true,
},
};
return (
<Calendar
style={styles.calendar}
markedDates={markedDates}
theme={{
selectedDayBackgroundColor: '#009688',
arrowColor: '#009688',
dotColor: '#009688',
todayTextColor: '#009688',
}}
/>
);
}
const styles = StyleSheet.create({
calendar: {
borderBottomWidth: 1,
borderBottomColor: '#e0e0e0',
},
});
export default CalendarView;
달력에 표시하기 위해 markedDates라는 객체를 사용합니다.
이 객체에 들어가는 키 값은 날짜의 'yyyy-MM-dd' 형태입니다.
표시를 원하는 각 날짜에 객체를 만들고, 거기에 marked 값을 true로 설정하면 날짜에 점이 나타납니다.
selected 값을 true로 설정하면 이 날짜를 선택했다는 의미로 날짜의 배경색을 변경합니다.
표시하는 색상은 theme이라는 Props를 통해 변경할 수 있습니다.
데이터를 달력과 연동하기
달력에 표시하는 법을 알았으니, 데이터의 날짜를 표시하도록 하겠습니다.
우선 CalendarScreen에서 LogContext의 logs 배열을 받아오겠습니다.
screens/CalendarScreen.js
import React ,{useContext} from 'react';
import CalendarView from '../components/CaendarView';
import LogContext from "../contexts/LogContext";
function CalendarScreen() {
const {log} = useContext(LogContext);
return <CalendarView />;
}
export default CalendarScreen;
다음으로 이 logs배열을 Calendar 컴포넌트의 markedDates Props 형태로 변환해줍니다.
변환된 객체는 CalendarView에 전달하겠습니다.
screens/CalendarScreen.js
import React, {useContext} from 'react';
import CalendarView from '../components/CaendarView';
import LogContext from '../contexts/LogContext';
import {format} from 'date-fns';
function CalendarScreen() {
const {logs} = useContext(LogContext);
const markedDates = logs.reduce((acc, current) => {
const formattedDate = format(new Date(current.date), 'yyyy-mm-dd');
acc[formattedDate] = {marked: true};
return acc;
}, {});
return <CalendarView markedDateds={markedDates} />;
}
export default CalendarScreen;
reduce 라는 함수는 배열의 내장함수입니다.
배열 안 값을 연산해 하나의 결과를 도출해낼 때 사용합니다.
const array = [0,1,2,3,4,5,6,7,8,10];
const sum = array.reduce((acc,current) => {
return acc+current;
} , 0 );
다음의 예시 코드를 보면 reduce는 첫번째 파라미터로
배열의 각 원소를 사용해 특정하는 값을 연산하는 함수를 넣습니다.
두번째 파라미터로 초깃값을 넣습니다.
첫 번째 파라미터에 넣은 함수의 acc는 accumulato를 의미하는데 ,이는 누적된 값이라는 뜻입니다.
current 는 현재 처리중인 값을 가르킵니다.
이 함수에서 반환한 값은 다음 원소를 처리할 때 acc 가 됩니다.
const markedDates = logs.reduce((acc, current) => {
const formattedDate = format(new Date(current.date), 'yyyy-mm-dd');
acc[formattedDate] = {marked: true};
return acc;
}, {});
다음 함수를 사용하는 초깃값은 비어있는 객체입니다.
그리고 각 원소의 날짜를 'yyyy-mm-dd'로 형태를 변환 후 변환된 값을 객체의 key로 사용해
{marked: true} 값을 지정해줍니다.
이렇게하면 로그가 작성된 날짜에만 해당 객체 값이 지정되어
로그 작성 날짜가 달력에 표시될 것입니다.
다음으로 selectDate라는 상태를 만들겠습니다.
이 값은 현재 선택된 날짜를 의미하며 기본값은 오늘 날짜입니다.
screens/CalendarScreen.js
import React, {useContext, useState} from 'react';
import CalendarView from '../components/CaendarView';
import LogContext from '../contexts/LogContext';
import {format} from 'date-fns';
function CalendarScreen() {
const {logs} = useContext(LogContext);
const [selectDate, setSelectDate] = useState(
format(new Date(), 'yyyy-mm-dd'),
);
const markedDates = logs.reduce((acc, current) => {
const formattedDate = format(new Date(current.date), 'yyyy-mm-dd');
acc[formattedDate] = {marked: true};
return acc;
}, {});
return (
<CalendarView
markedDateds={markedDates}
selectedDate={selectDate}
onSelectDate={setSelectDate}
/>
);
}
export default CalendarScreen;
selectedDate와 setSelectDate 또한 CalendarView에 전달합니다.
setSelectedDate는 onSelectDate라는 이름으로 설정하겠습니다.
그 다음 CalendarView에서 markedSelectedDate라는 새로운 객체를 만들어
현재 날짜에 selected: true를 설정하겠습니다.
components.CalendarView.js
import React from 'react';
import {StyleSheet} from 'react-native';
import {Calendar} from 'react-native-calendars/src/index';
function CalendarView({markedDates, selectedDate, onSelectDate}) {
const markedSelectedDate = {
...markedDates,
[selectedDate]: {
selected: true,
marked: markedDates[selectedDate]?.marked,
},
};
return (
<Calendar
style={styles.calendar}
markedDates={markedSelectedDate}
theme={{
selectedDayBackgroundColor: '#009688',
arrowColor: '#009688',
dotColor: '#009688',
todayTextColor: '#009688',
}}
/>
);
}
(...)
이제 달력에서 날짜를 선택했을 때 onSelectDate를 호출해야합니다.
이는 Calendar에 onDayPress라는 Porps를 설정해 구현하겠습니다.
components/CalendarVeiw.js - return
return (
<Calendar
style={styles.calendar}
markedDates={markedSelectedDate}
onDayPress={day => {
onSelectDate(day.dateString);
}}
theme={{
selectedDayBackgroundColor: '#009688',
arrowColor: '#009688',
dotColor: '#009688',
todayTextColor: '#009688',
}}
/>
);
여기서 day 객체의 구성은 다음과 같습니다.
{
"dateString" : "2023-03-30:,
"day" : 30,
"month" : 3,
"timestamp" : 1680220800000,
'year' : 2023
}
'코딩생활 > ReactNative' 카테고리의 다른 글
[React Native] 3-13 날짜 및 시간 수정 기능 구현하기 (0) | 2023.04.04 |
---|---|
[React Native] 3-12 달력 기능 구현하기 (2) (0) | 2023.04.03 |
[React Native] 3-11 검색 기능 구현하기 (2) (0) | 2023.03.30 |
[React Native] 3-11 검색 기능 구현하기 (1) (0) | 2023.03.27 |
[React Native] 3-10 삭제 기능 구현하기 (0) | 2023.03.26 |
댓글