이제 로그를 작성할 때,
react-native-modal-datetime-picker라는 라이브러리를 사용하여
로그의 날짜 및 시간을 수정하는 기능을 구현해보겠습니다.
$ yarn add react-native-modal-datetime-picker @react-native-community/datetimepicker
이 라이브러리는 Ios와 안드로이드에 각각의 플랫폼에 특화된 날씨/시간 선택 컴포넌트를 제공합니다.
이 라이브러리는 네이티브 코드를 사용하기 때문에 시뮬레이터를 재실행해주어야합니다.
우선 WriteScreen에서 date 상태를 만들어줍니다.
그리고 onSave에서 수정하거나 새로 저장할 때 date 상태를 사용하도록 변경합니다.
WriteHeader에는 date와 onChangeDate를 Props로 넣어주겠습니다.
screnns/WriteScreen.js
(...)
function WriteScreen({route}) {
const log = route.params?.log;
const [title, setTitle] = useState(log?.title ?? '');
const [body, setBody] = useState(log?.body ?? '');
const navigation = useNavigation();
//추가
const [date, setDate] = useState(log ? new Date(log.date) : new Date());
// ----
const {onCreate, onModify, onRemove} = useContext(LogContext);
(...)
const onSave = () => {
console.log(title);
if (log) {
onModify({
id: log.id,
date: date.toISOString(), // 수정
title,
body,
});
} else {
onCreate({
title,
body,
date: date.toISOString(), // 수정
});
}
navigation.goBack();
};
return (
<SafeAreaView style={styles.block}>
<KeyboardAvoidingView
style={styles.avoidingView}
behavior={Platform.OS === 'ios' ? 'padding' : undefined}>
<WriteHeader
onSave={onSave}
onAskRemove={onAskRemove}
isEditing={!!log}
//추가
date={date}
onChangeDate={setDate}
/>
<WriteEditor
title={title}
body={body}
onChangeTitle={setTitle}
onChangeBody={setBody}
/>
</KeyboardAvoidingView>
</SafeAreaView>
);
}
(...)
export default WriteScreen;
이 후엔 WriteHeader에서 Pros로 받아온 date를 보여주도록 수정해야 합니다.
이는 컴포넌트 중앙에 위치시키겠습니다.
position: 'absolute' 속성을 가진 View를 사용해 간단하게 레이아웃을 구성해보겠습니다.
conponents/WriteHeader.js
import React from 'react';
import {View, StyleSheet, Pressable, Text} from 'react-native';
import {useNavigation} from '@react-navigation/native';
import TransparentCircleButton from './TransparentCircleButton';
import {format} from 'date-fns';
import {ko} from 'date-fns/locale';
function WriteHeader({onSave, onAskRemove, isEditing, date, onChangeDate}) {
const navigation = useNavigation();
const onGoBack = () => {
navigation.goBack();
};
return (
<View style={styles.block}>
<View style={styles.iconButtonWrapper}>
<TransparentCircleButton
onPress={onGoBack}
name="arrow-back"
color={'#424242'}
/>
</View>
<View style={styles.buttons}>
{isEditing && (
<TransparentCircleButton
name="delete-forever"
color={'#ef5350'}
hasMarginRight
onPress={onAskRemove}
/>
)}
<TransparentCircleButton
name={'check'}
color={'#009688'}
onPress={onSave}
/>
</View>
<View style={styles.center}>
<Pressable>
<Text>{format(new Date(date), 'PPP', {locale: ko})}</Text>
</Pressable>
<View style={styles.separator} />
<Pressable>
<Text>{format(new Date(date), 'p', {locale: ko})}</Text>
</Pressable>
</View>
</View>
);
}
const styles = StyleSheet.create({
block: {
height: 48,
paddingHorizontal: 8,
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'space-between',
},
buttons: {
flexDirection: 'row',
alignItems: 'center',
},
center: {
position: 'absolute',
left: 0,
right: 0,
top: 0,
bottom: 0,
alignItems: 'center',
justifyContent: 'center',
zIndex: -1,
flexDirection: 'row',
},
separator: {
width: 8,
},
});
export default WriteHeader;
center 스타일에서 position : 'absoulte'를 설정하고 모든 값을 0으로 설정했습니다.
이는 컴포넌트의 상위 컴포넌트 크기만큼 꽉 채우겠다는 의미입니다.
zIndex라는 속성은 컴포넌트가 다른 컴포넌트와 위치가 중첩될 때 앞 레이어에 나타날지
뒤 레이어에 나타날지 경정하는 값인데, 기본적으로 높은 값이 더 낮은 값을 가진 컴포넌트를 가립니다.
이제는 날짜 또는 시간을 누르면 DateTimePickerModal 컴포넌트를 보여줘서
날짜를 수정할 수 있게 만들어보겠습니다.
사용법은 다음과 같습니다.
<DateTimePickerModal
onConfirm={onConfirm}
onCancel={onCancel}
mode={mode}
date={date}
isVisivle={visible}
/>
- onConfirm : 날짜를 선택했을 때 호출되는 함수입니다. 함수의 파라미터는 Date 객체입니다.
- onCancel : 날짜 선택을 취소했을 때 호출되는 함수입니다.
- mode : 모달의 모드를 설정합니다. 설정할 수 있는 값은 date, time, datetime입니다.
- date : 컴포넌트에서 보여졌을 때 초깃값으로 설정할 Date 객체 타입의 값입니다.
- isVisible: 이 값을 true로 설정하면 모달이 보이고, false로 설정하면 모달이 사라집니다
날짜를 눌렀을 때는 'date' 모드, 시간을 선택했을 때는 'time'모드를 사용하겠습니다.
components/WriteHeader.js
import React, {useState} from 'react';
import {View, StyleSheet, Pressable, Text} from 'react-native';
import {useNavigation} from '@react-navigation/native';
import TransparentCircleButton from './TransparentCircleButton';
import {format} from 'date-fns';
import {ko} from 'date-fns/locale';
import DateTimePickerModal from 'react-native-modal-datetime-picker';
function WriteHeader({onSave, onAskRemove, isEditing, date, onChangeDate}) {
(...)
//추가
const [mode, setMode] = useState('date');
const [visible, setVisible] = useState(false);
const onPressDate = () => {
setMode('date');
setVisible(true);
};
const onPressTime = () => {
setMode('time');
setVisible(true);
};
const onConfirm = selectedDate => {
setVisible(false);
onChangeDate(selectedDate);
};
const onCancel = () => {
setVisible(false);
};
//-----
return (
(...)
<View style={styles.center}>
<Pressable onPress={onPressDate}>
<Text>{format(new Date(date), 'PPP', {locale: ko})}</Text>
</Pressable>
<View style={styles.separator} />
<Pressable onPress={onPressTime}>
<Text>{format(new Date(date), 'p', {locale: ko})}</Text>
</Pressable>
</View>
<DateTimePickerModal
isVisible={visible}
mode={mode}
onConfirm={onConfirm}
onCancel={onCancel}
date={date}
/>
</View>
);
}
(...)
반영이 잘 되나요?
'코딩생활 > ReactNative' 카테고리의 다른 글
[React Native] 3-12 달력 기능 구현하기 (2) (0) | 2023.04.03 |
---|---|
[React Native] 3-12 달력 기능 구현하기 (1) (0) | 2023.03.31 |
[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 |
댓글