Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 |
Tags
- 엘리스 AI 트랙 5기
- 자바스크립트 split()
- [파이썬 실습] 중급 문제
- 개발공부
- RN 프로젝트
- HTML
- 자바스크립트 날씨 웹 만들기
- JavaScript
- 부트캠프
- reactnativecli
- 자바스크립트 reduce()
- 자바스크립트 sort()
- 코드스테이츠
- 개발일기
- 자바스크립트 날씨
- 프로그래머스
- 프론트개발공부
- 날씨 웹 만들기
- 리트코드
- 엘리스
- 자바스크립트
- [AI 5기] 연습 문제집
- [파이썬 실습] 심화 문제
- 코딩부트캠프
- leetcode
- 프론트개발
- 간단한 날씨 웹 만들기
- 삼항연산자
- 엘리스 ai 트랙
- [파이썬 실습] 기초 문제
Archives
- Today
- Total
개발조각
[React-native CLI] RN 기록화면 구현하기 3부 (realm에 create, update하기) 본문
React-Native/[프로젝트] 택시 운행관리 기록장
[React-native CLI] RN 기록화면 구현하기 3부 (realm에 create, update하기)
개발조각 2024. 3. 19. 00:37728x90
반응형
생각보다 길어져서 3부까지 작성하게 되었습니다. (2 부면 충분할 줄 알았더니 엄청 기네요.)
이번 3부에서는 realm에 저장하는 코드에 대해 작성하겠습니다.
구현화면
저장하기를 클릭하면
새로운 날짜에 대한 데이터를 저장할 경우 create 저장하고,
기존에 있던 날짜에 대한 데이터를 저장할 경우 update 저장되게 하도록 구현하면 됩니다.
기존코드
1부에서 screens/Record.tsx에서 해당 날짜에 따라 데이터를 CREATE를 해야 되는지 UPDATE를 해야 되는지 useState로 지정해 주었습니다.
screens/Record.tsx
const Record = ({route}: profileProps) => {
const {postDate} = route.params;
const realm = useRef<Realm>();
const [selectDate, setSelectDate] = useState(postDate); // 선택한 날짜
const [record, setRecord] = useState(''); // CREATE or UPDATE
const [state, dispatch] = useReducer(
RecordReducer.reducer,
RecordReducer.initialRecord,
);
// selectDate가 realm에 있는지 체크
const readDB = useCallback(() => {
const selectDateData = realm.current
?.objects('Record')
.filtered(`date = '${selectDate}'`)[0];
if (selectDateData) {
setRecord('UPDATE'); // 데이터 수정
dispatch({type: 'initialize', payload: selectDateData});
} else {
setRecord('CREATE'); // 데이터 생성
const initialData = {...RecordReducer.initialRecord, date: selectDate};
dispatch({type: 'initialize', payload: initialData});
}
}, [selectDate]);
...
}
readDB에서 선택한 날짜에 따라 realm에 있는 데이터인지 확인을 하고,없으면 record state에 CREATE, 있으면 UPDATE를 넣어주었습니다.
새로 생성되는 운행정보는 realm에 create 하고, 기존의 데이터를 수정하면 realm에 update 하기
createDB
const createDB = () => {
realm.current?.write(() => {
realm.current?.create('Record', state);
});
console.log('데이터가 생성되었습니다.');
readDB();
};
updateDB
const updateDB = () => {
const selectDateData = realm.current
?.objects('Record')
.filtered(`date = '${selectDate}'`)[0];
if (selectDateData) {
realm.current?.write(() => {
selectDateData.card = state.card;
selectDateData.cash = state.cash;
selectDateData.lpgInjectionVolume = state.lpgInjectionVolume;
selectDateData.lpgUnitPrice = state.lpgUnitPrice;
selectDateData.mileage = state.mileage;
selectDateData.businessDistance = state.businessDistance;
selectDateData.toll = state.toll;
selectDateData.operatingAmount = state.operatingAmount;
selectDateData.lpgChargeAmount = state.lpgChargeAmount;
selectDateData.fuelEfficiency = state.fuelEfficiency;
selectDateData.lpgUsage = state.lpgUsage;
});
console.log('데이터가 수정되었습니다.');
readDB();
}
};
이렇게 작성하기 싫은데, 한 번에 업데이트하는 방법은 없어서 기본키인 date 빼고 다 작성해 주었습니다.
screens/Record.tsx
// react, react-native
import {useCallback, useEffect, useReducer, useRef, useState} from 'react';
import {NativeStackScreenProps} from '@react-navigation/native-stack';
// library
import Realm from 'realm';
// realm
import {RecordSchema} from '../realm/schema';
// component
import SubHeader from '../components/record/SubHeader';
import DrivingInfoRecord from '../components/record/DrivingInfoRecord';
import DrivingInfo from '../components/record/DrivingInfo';
import ButtonWrap from '../components/record/ButtonWrap';
// style
import {Record as Style} from '../styles/record.styles';
import * as RecordReducer from '../reducers/recordReducer';
type RootStackParamList = {
Profile: {postDate: string};
};
type profileProps = NativeStackScreenProps<RootStackParamList, 'Profile'>;
// 추가하기(+버튼 클릭시), 수정하기(달력에서 날짜 클릭, 수정 클릭)
const Record = ({route}: profileProps) => {
const {postDate} = route.params;
const realm = useRef<Realm>();
const [selectDate, setSelectDate] = useState(postDate); // 선택한 날짜
const [record, setRecord] = useState(''); // CREATE or UPDATE
const [state, dispatch] = useReducer(
RecordReducer.reducer,
RecordReducer.initialRecord,
);
// selectDate가 realm에 있는지 체크
const readDB = useCallback(() => {
const selectDateData = realm.current
?.objects('Record')
.filtered(`date = '${selectDate}'`)[0];
if (selectDateData) {
setRecord('UPDATE'); // 데이터 수정
dispatch({type: 'initialize', payload: selectDateData});
} else {
setRecord('CREATE'); // 데이터 생성
const initialData = {...RecordReducer.initialRecord, date: selectDate};
dispatch({type: 'initialize', payload: initialData});
}
}, [selectDate]);
// selectDate가 변경되면 readDB()렌더링
useEffect(() => {
readDB();
}, [readDB, selectDate]);
const openLocalDB = async () => {
realm.current = await Realm.open({schema: [RecordSchema]});
console.log('realmDB 열기!');
readDB();
};
// realmDB 열기, 닫기
useEffect(() => {
openLocalDB();
return () => {
realm.current?.close();
console.log('realmDB 닫기!');
};
}, []);
const createDB = () => {
realm.current?.write(() => {
realm.current?.create('Record', state);
});
console.log('데이터가 생성되었습니다.');
readDB();
};
const updateDB = () => {
const selectDateData = realm.current
?.objects('Record')
.filtered(`date = '${selectDate}'`)[0];
if (selectDateData) {
realm.current?.write(() => {
selectDateData.card = state.card;
selectDateData.cash = state.cash;
selectDateData.lpgInjectionVolume = state.lpgInjectionVolume;
selectDateData.lpgUnitPrice = state.lpgUnitPrice;
selectDateData.mileage = state.mileage;
selectDateData.businessDistance = state.businessDistance;
selectDateData.toll = state.toll;
selectDateData.operatingAmount = state.operatingAmount;
selectDateData.lpgChargeAmount = state.lpgChargeAmount;
selectDateData.fuelEfficiency = state.fuelEfficiency;
selectDateData.lpgUsage = state.lpgUsage;
});
console.log('데이터가 수정되었습니다.');
readDB();
}
};
return (
<Style.container>
{/* 헤더 */}
<SubHeader selectDate={selectDate} setSelectDate={setSelectDate} />
<Style.scrollView>
{/* 기본 운행 정보 기록하기 */}
<DrivingInfoRecord state={state} dispatch={dispatch} />
{/* 운행정보 */}
<DrivingInfo state={state} />
</Style.scrollView>
{/* 취소, 저장 */}
<ButtonWrap record={record} createDB={createDB} updateDB={updateDB} />
</Style.container>
);
};
export default Record;
이제 취소, 저장 버튼에 가서 적용해 주면 됩니다.
components/record/ButtonWrap.tsx
// component
import BasicsButton from '../common/BasicsButton';
// style
import {ButtonWrap as Style} from '../../styles/record.styles';
import {useNavigation} from '@react-navigation/native';
interface PropsType {
record: string;
createDB: () => void;
updateDB: () => void;
}
const ButtonWrap = ({record, createDB, updateDB}: PropsType) => {
const navigation = useNavigation();
// 뒤로가기
const onGoBackPress = () => {
navigation.goBack();
};
const onSavePress = () => {
if (record === 'CREATE') {
createDB();
} else {
updateDB();
}
};
return (
<Style.container>
<BasicsButton text="취소" option="cancel" onButtonPress={onGoBackPress} />
<BasicsButton text="저장" onButtonPress={onSavePress} />
</Style.container>
);
};
export default ButtonWrap;
주요 코드
const onSavePress = () => {
if (record === 'CREATE') {
createDB();
} else {
updateDB();
}
navigation.goBack();
};
components/common/BasicsButton.tsx
// style
import {BasicsButton as Style} from '../../styles/common.styles';
interface PropsType {
text: string;
option?: 'cancel' | 'confirm';
onButtonPress: () => void;
}
const BasicsButton = ({text, option = 'confirm', onButtonPress}: PropsType) => {
return (
<Style.button option={option} onPress={onButtonPress}>
<Style.text option={option}>{text}</Style.text>
</Style.button>
);
};
export default BasicsButton;
이렇게 하고 저장을 클릭하면
728x90
반응형
'React-Native > [프로젝트] 택시 운행관리 기록장' 카테고리의 다른 글
[React-native CLI] RN navigation.navigate 타입 오류 수정 (0) | 2024.03.22 |
---|---|
[React-native CLI] RN에서 Realm 세팅 및 사용(구조 전면 교체) (0) | 2024.03.19 |
[React-native CLI] RN 기록화면 구현하기 2부(useReducer 사용하기) (0) | 2024.03.18 |
[React-native CLI] RN 기록화면 구현하기 1부 (선택한 날짜에 따라 Creact, Update하기) (0) | 2024.03.18 |
[React-native CLI] RN에서 react-native-calendars 사용하기 (0) | 2024.03.18 |
Comments