3장 할일 목록 만들기 I 3.1 프로젝트 기반 다지기
3.1.1 프로젝트 생성하기
$ npx react-native init TodoApp
$npx create-react-native-app TodoApp 과 $ npx react-native init TodoApp 명령어의 프로젝트 생성 차이는 아직 모르겠습니다(..)
$yarn android
//$ yarn ios
/*프로젝트 내에 android app기동을 위한 커맨드 입니다.
기존에 띄워둔 (Metro 창이 있다면 닫고 기동 해주세요)*/
vs Code tip
Ctrl+` 으로 terminel을 간편하게 열 수 있습니다
App.js 컨포넌트는 main컴포넌트 입니다.
3.1.2 오늘 날짜를 알려주는 DateHead 컴포넌트 만들기
../components/DateHead.js
날짜 하드 코딩 하는법
색상 참조URL->> Material Color( https://material.io/resources/color )
App.js 에 다음과 같이 호출 하여 header를 구성합니다.
import DateHead from './components/DateHead';
javascript 현재시간 가져오기는 다음과 같습니다.
const today = new Date();
자스 Date관련 독스URL http://bit.ly/mdn-date
Date - JavaScript | MDN
JavaScript Date 객체는 시간의 한 점을 플랫폼에 종속되지 않는 형태로 나타냅니다. Date 객체는 1970년 1월 1일 UTC(협정 세계시) 자정과의 시간 차이를 밀리초로 나타내는 정수 값을 담습니다.
developer.mozilla.org
자스의 실행은 왼쪽의 extension에서 Code Runner 를 다운받아서 우상단의 run을 눌러주세요. ('run' hot Key는 [Ctrl+Alt+N] 입니다)
tip! 디버그모드는 시뮬레이터에서 [Ctrl+M] 으로 진입 가능합니다.
const d = new Date();
const year = d.getFullYear();
const month = d.getMonth() + 1;
const day = d.getDate();
Date 객체에서 연, 월(+1), 일을 추출하는 방법입니다.
(월은 month값이 0~11까지이기때문에 0+1부터 시작할 수 있도록 합니다.)
year , month , day 값이 있는 상황에서 YYYY 년 MM 월 DD 일을 표현하려면...
const formatted = year + '년 ' + month + '월 ' + day + '일';
아래는 템플릿 리터럴 문법 이라는 건데 ``(백틱) 을 이용합니다.(``대신 ""도 결과는 같지만 코드의 가독성이 떨어집니다)
const formatted = `${year}년 ${month}월 ${day}일`;
위 변수를 선언 후에 리턴 함수 안에 {$변수} 의 형태로 출력 할 수 있도록 합니다.
JSX이므로 다음과 같이 작성도 가능합니다.
function DateHead({date}) {
const year = date.getFullYear();
const month = date.getMonth() + 1;
const day = date.getDate();
return (
<Text style={styles.dateText}>
{year}년 {month}월 {day}일
</Text>
);
}
3.1.3 StatusBar 색상 바꾸기
== 최상단의 StatusBar 색상을 헤더와 맞추는 작업입니다.
import {View, Text, StyleSheet, StatusBar} from 'react-native';
statusBar 호출을 위해 다음과 같이 import 선언해주시고,
return( <StatusBar backgroundColor="#26a69a" />
);
과 같은 형태로 코드를 작성해줍니다.
iOS 관련 내용은 생략하겠습니다 ( SafeAreaView .여백을 없앤 후 View로 차우기)
SafeAreaView : 상단과 하단에 여백을 설정하여 디바이스 안에 콘텐츠를 보일 수 있도록 합니다. (해본 후 지우세요)
function App() {
return (
<SafeAreaView style={{flex: 1}}>
<View style={{flex: 1, backgroundColor: 'blue'}} />
</SafeAreaView>
);
}
3.1.3.1 react-native-safe-area-context 서드 파티 라이브러리 사용하기
$ yarn add react-native-safe-area-context
서드파티 관련 자세한 내용은 아래URL에서 참고 바랍니다.
https://github.com/th3rdwave/react-native-safe-area-context
GitHub - th3rdwave/react-native-safe-area-context: A flexible way to handle safe area insets in JS. Also works on Android and We
A flexible way to handle safe area insets in JS. Also works on Android and Web! - GitHub - th3rdwave/react-native-safe-area-context: A flexible way to handle safe area insets in JS. Also works on ...
github.com
react-native-safe-area-context 라이브러리를 적용 할 때는 SafeAreaProvider 컴포넌트를 사용해 기존 내용을 모두 감싸줘야 합니다
import {SafeAreaProvider} from 'react-native-safe-area-context';
import로 호출 해주시고
return (
<SafeAreaProvider>
<DateHead date={today} />
</SafeAreaProvider>
);
}
이런 식으로 구현해 줍니다.
<SafeAreaView/>는 항상 <SafeAreaProvider/> 의 자식요소로 위치해야합니다.
return (
<SafeAreaProvider>
<SafeAreaView edges={['bottom']}>
<DateHead date={today} />
</SafeAreaView>
</SafeAreaProvider>
);
}
태그 안에 edges={['bottom']} props(properties)를 설정했습니다.
>>최상단의 StatusBar 와 DateHead가 겹치는 현상이 발생하게 됩니다.
StatusBar의 높이와 일치하는 view공백으로 처리를 합니다. ( react -native -safe -area -context lib에 구현되어 있습니다. )
3.1.3.2 useSafeAreaInsets로 StatusBar 높이 구하기
DateHead.js에 useSafeAreaInsets를 호출하여 사용합니다.
import {useSafeAreaInsets} from 'react-native-safe-area-context';
선언 후 다음과 같이 사용합니다.
const {top} = useSafeAreaInsets();
return (
<>
<View style={[styles.statusBarPlaceholder, {height: top}]} />
<StatusBar backgroundColor="#26a69a" />
</>
);
}
3.1.3.3 StatusBar 내용 색상 변경하기
barStyle porps를 선언하여 색상을 변경할 수 있습니다.
<StatusBar backgroundColor="#26a69a" barStyle="light-content" />
입력 값은 dark -content (어두운 내용), light -content (밝은 내용), default (시스템 기본 설정)로 3가지가 있습니다.
3.1.4 레이아웃 준비하기
AddTodo 라는 컴포넌트를 배치할 예정입니다.
디바이스의 하단부: AddTodo.js
components/AddTodo.js 생성해줍니다.
import React from 'react';
import {View, StyleSheet} from 'react-native';
function AddTodo() {
return <View style={styles.block} />;
}
const styles = StyleSheet.create({
block: {
height: 64,
backgroundColor: 'red',
},
});
export default AddTodo;
AddTodo() {}함수를 다음과 같이 선언해줍니다.
import AddTodo from './components/AddTodo';
return (
<SafeAreaProvider>
<SafeAreaView edges={['bottom']}>
<DateHead date={today} />
<AddTodo />
</SafeAreaView>
</SafeAreaProvider>
);
}
일단은 Header의 {today}밑에 <AddTodo/>가 위치하도록 작성합니다.
if(Todos != null) {있다면 둘 사이에 할일 항목 리스트를 보여주기}
else{없다면 이미지와 문구를 보여주기 )}
없다면 의 화면은 components에 Empty.js로 구현합니다.
import React from 'react';
import {View, Text, StyleSheet} from 'react-native';
function Empty() {
return (
<View style={styles.block}>
//<Image source={require('../assets/images/circle.png')}
//style={styles.image}
//resizeMode="cover"
/>
<Text style={styles.description}>야호! 할일이 없습니다.</Text>
</View>
);
}
const styles = StyleSheet.create({
block: {
flex: 1,
alignItems: 'center',
justifyContent: 'center',
},
/*
* image: {
* width: 300,
* height: 200,
* },
*/
description: {
fontSize: 24,
color: '#9e9e9e',
},
});
export default Empty;
lock 스타일에 flex : 1
->자신이 차지할 수 있는 영역을 모두 차지
alignItems& justifyContent = center
->내용이 중앙에 위치
descriptio
-> 폰트 크기와 색상을 설정
App.js에 다음과 같이 호출하여 적용합니다.
import React from 'react';
import {StyleSheet} from 'react-native';
import DateHead from './components/DateHead';
import {SafeAreaProvider, SafeAreaView} from 'react-native-safe-area-context';
import AddTodo from './components/AddTodo';
import Empty from './components/Empty';
function App() {
const today = new Date();
return (
<SafeAreaProvider>
<SafeAreaView edges={['bottom']} style={styles.block}>
<DateHead date={today} />
<Empty />
<AddTodo />
</SafeAreaView>
</SafeAreaProvider>
);
}
const styles = StyleSheet.create({
block: {
flex: 1,
},
});
export default App;
여기까지가 레이아웃구성 입니다.
---------------------------
3.1.5 이미지 사용하기
해상도, 즉 선명함을 위해 디바이스 기종에 따라 다른 이미지 사용을 필요로 합니다.
이미지 다운URL - http://bit.ly/chapter-3-images
이미지소스의 {경로}를 입력할 때는 require () 라는 함수로 입력해야 합니다.
3.1.5.1 resizeMode 이해하기
resizeMode는 총 5가지 값으로 설정할 수 있습니다.
resizeMode 값
description
cover
resizeMode를 따로 설정하지 않으면 이 값을 기본값으로 지정합니다. 이 옵션은 이미지의 가로 세로 비율을 유지한 상태로 이미지를 리사이징합니다. 이미지와 뷰의 가로 세로 비율이 일치하지 않을 경우 이미지의 일부분이 잘립니다.
contain
이미지의 가로 세로 비율을 유지한 상태로 이미지를 리사이징하며 이미지의 모든 영역이 뷰 안에 보이게 합니다.
stretch
뷰의 크기대로 이미지를 리사이징합니다. 이 과정에서 이미지의 가로 세로 비율이 원본과 달라질 수 있습니다.
repeat
뷰의 크기가 이미지의 크기보다 크면 바둑판식으로 이미지를 반복합니다.
center
이미지를 뷰 중앙에 둡니다. contain과 마찬가지로 이미지의 모든 영역이 뷰 안에 보이게 합니다. 단, 뷰가 이미지보다 크면 이미지의 크기가 커지지 않고 원본 사이즈를 유지합니다.
3.1.5.2 외부 이미지 사용하기
객체변수 : 클래스에 선언된 변수
const source = {uri: 'https://via.placeholder.com/150'};
return (
<View style={styles.block}>
<Image
source={source}
style={styles.image}
resizeMode="contain"
/>
<Text style={styles.description}>야호! 할일이 없습니다.</Text>
</View>
);
-------------------------------------------------------------------------
return (
<View style={styles.block}>
<Image
source={require('../assets/images/young_and_happy.png')}
style={styles.image}
/>
<Text style={styles.description}>야호! 할일이 없습니다.</Text>
</View>
);
외부이미지 보여주기
3.2 TextInput으로 사용자 키보드 입력받기
3.2.1 KeyboardAvoidingView로 키보드가 화면을 가리지 않게 하기 3.2.2 useState로 텍스트 상태 값 관리하기 3.2.3 커스텀 버튼 만들기 3.2.4 TextInput에 onSubmitEditing 및 returnKeyType 설정하기 3.3 정리
4장 할일 목록 만들기 II 4.1 불변성을 지키면서 객체와 배열 업데이트하기 4.1.1 불변성을 지켜야 하는 이유 4.1.2 배열의 불변성을 지키는 방법 4.2 todos 상태 만들기 및 FlatList로 항목 화면에 나타내기 4.2.1 todos 상태 만들기 4.2.2 TodoList 컴포넌트 만들기 4.2.3 TodoItem 컴포넌트 만들기 4.2.4 항목 사이에 구분선 보여주기 4.2.5 완료한 항목에 다른 스타일 적용하기 4.3 새 항목 등록하기 4.4 할일 완료 상태 토글하기 4.5 항목 삭제하기 4.5.1 벡터 아이콘 사용하기 4.5.2 항목 삭제 함수 만들기 4.5.3 항목을 삭제하기 전에 한번 물어보기 4.6 AsyncStorage로 앱이 꺼져도 데이터 유지하기 4.6.1 Promise가 무엇인가요? 4.6.2 AsyncStorage 설치하기 4.6.3 AsyncStorage의 기본 사용법 4.6.4 AsyncStorage 적용하기 4.7 정리