https://github.com/ssi02014/react-native-todoapp
๐ฑ ๋ฆฌ์กํธ ๋ค์ดํฐ๋ธ ToDoList App
https://github.com/ssi02014/react-native-todoapp
Last synced: 19 days ago
JSON representation
๐ฑ ๋ฆฌ์กํธ ๋ค์ดํฐ๋ธ ToDoList App
- Host: GitHub
- URL: https://github.com/ssi02014/react-native-todoapp
- Owner: ssi02014
- Created: 2021-04-07T04:23:02.000Z (over 4 years ago)
- Default Branch: master
- Last Pushed: 2021-04-07T14:26:13.000Z (over 4 years ago)
- Last Synced: 2024-12-30T06:44:58.633Z (9 months ago)
- Language: JavaScript
- Homepage:
- Size: 341 KB
- Stars: 0
- Watchers: 2
- Forks: 1
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# ๐ป React-Native-TodoApp
### React-Native-TodoApp ์ ์ฅ์
## ๐ฅ App View
![]()
## ๐จ๐ปโ๐ป ๊ธฐ์ ์คํ
1. React-Native
2. Styled-Components - styling
3. AsyncStorage
4. Google Material Design - icon
## ๐จ๐ปโ๐ป SafeAreaView, StatusBar Component
- SafeAreaView๋ ์์ดํฐ11๊ณผ ๊ฐ์ ๋ ธ์น ๋์์ธ๋๋ฌธ์ ๊ฐ๋ ค์ง๋ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํด ์ฃผ๋ ์ปดํฌ๋ํธ์ด๋ค.
- StatusBar๋ ์๋๋ก์ด๋ Title ์ปดํฌ๋ํธ๊ฐ ์ํ ๋ฐ(Status Bar)์ ๊ฐ๋ ค์ง๋ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํด์ฃผ๋ ์ปดํฌ๋ํธ์ด๋ค.
- StatusBar์์ barStyle์ ํตํด ์ํ ๋ฐ์ ๋ด์ฉ์ ์์ ์์ ํ ์ ์์ต๋๋ค.
- StatusBar์์ backgroundColor๋ ์๋๋ก์ด๋์์๋ง ์ ์ฉ๋๋ ์์ฑ์ด๋ฉฐ ์ํ ๋ฐ์ ๋ฐํ์์ ์์ ํ ์ ์์ต๋๋ค.```javascript
//SageAreaView
const Container = styled.SafeAreaView`
(...)
`;
``````javascript
//StatusBar
import { StatusBar } from 'react-native';
```
## ๐จ๐ปโ๐ป Dimensions, useWindowDimensions
- Dimensions, useWindowDimensions ๋ชจ๋ ํ์ฌ ๊ธฐ๊ธฐ์ ํ๋ฉด ํฌ๊ธฐ๋ฅผ ์ ์ ์๊ณ , ์ด๋ฅผ ์ด์ฉํด ๋ค์ํ ํฌ๊ธฐ์ ๊ธฐ๊ธฐ์ ๋์ผํ ๋ชจ์ต์ผ๋ก ์ ์ฉ๋ ์ ์๋๋ก ์ฝ๋๋ฅผ ์์ฑํ ์ ์๋ค.
- Dimensions๋ ์ฒ์ ๊ฐ์ ๋ฐ์์์ ๋์ ํฌ๊ธฐ๋ก ๊ณ ์ ๋๊ธฐ ๋๋ฌธ์ ๊ธฐ๊ธฐ๋ฅผ ํ์ ํด์ ํ๋ฉด์ด ์ ํ๋๋ฉด ๋ณํ๋ ํ๋ฉด์ ํฌ๊ธฐ๊ฐ ์ผ์นํ์ง ์๋ ๋ฌธ์ ๊ฐ ์๋ค.
- useWindowDimensions๋ ๋ฆฌ์กํธ ๋ค์ดํฐ๋ธ์์ ์ ๊ณตํ๋ Hooks์ค ํ๋๋ก, ํ๋ฉด์ ํฌ๊ธฐ๊ฐ ๋ณ๊ฒฝ๋๋ฉด ํ๋ฉด์ ํฌ๊ธฐ, ๋๋น ,๋์ด๋ฅผ ์๋์ผ๋ก ์ ๋ฐ์ดํธํ๋ค.
```javascript
//Dimensions
import { Dimensions } from 'react-native';const Input = () => {
const width = Dimensions.get('window').width;return
}
``````javascript
//useWindowDimensions
import { useWindowDimensions } from 'react-native';const Input = () => {
const width = useWindowDimensions().width;return
}
```
## ๐จ๐ปโ๐ป TextInput ์์ฑ
- autoCapitalize: ์๋์ผ๋ก ๋๋ฌธ์ ์ ํ(iOS)
- autoCorrect: ์๋ ์์ ๊ธฐ๋ฅ(iOS)
- returnKeyType: ํค๋ณด๋์ ์๋ฃ ๋ฒํผ ์ค์ (iOS)
- keyboardApperance: ํค๋ณด๋ ์ ์ค์ (iOS)```javascript
```## ๐จ๐ปโ๐ป Google Material Design
๐ https://material.io/resources/icons/?style=baseline
- ํ๋ก์ ํธ์ ์ฌ์ฉํ ์์ด์ฝ ์ด๋ฏธ์ง๋ฅผ ๋ค์ด๋ฐ์ ์ ์์ต๋๋ค.
- iOS๋ก ๋ค์ด๋ฐ์ผ๋ฉด x2, x3 ์ฌ์ด์ง์ ์์ด์ฝ์ด ํจ๊ป ์์ต๋๋ค.
- ํ์ผ๋ช ์ ๋์ผํ ์ด๋ฆ์ ์ฌ์ฉํ๋ฉด์ @2x, @3x๋ฅผ ๋ถ์ด๋ฉด ๋ฆฌ์กํธ ๋ค์ดํฐ๋ธ์์ ํ๋ฉด ์ฌ์ด์ฆ์ ์๋ง์ ํฌ๊ธฐ์ ์ด๋ฏธ์ง๋ฅผ ์๋์ผ๋ก ๋ถ๋ฌ์ ์ฌ์ฉํ ์ ์์ต๋๋ค.
## ๐จ๐ปโ๐ป Image, IconButton Component
- Image Component๋ ๋ฆฌ์กํธ ๋ค์ดํฐ๋ธ์์ ์ ๊ณตํ๋ ์ปดํฌ๋ํธ์ด๋ฉฐ, ํ๋ก์ ํธ์ ์๋ ์ด๋ฏธ์ง ํ์ผ์ ๊ฒฝ๋ก๋ URL์ ์ด์ฉํ์ฌ ์๊ฒฉ์ ์๋ ์ด๋ฏธ์ง๋ฅผ ๋ ๋๋งํ ์ ์์ต๋๋ค.
- tint-color๋ฅผ ํตํด ์์ด์ฝ์ ์๊น์ ์ค ์ ์๋ค.```javascript
const Icon = styled.Image`
tint-color: ${({theme}) => theme.text};
width: 30px;
height: 30px;
margin: 10px;
`;const IconButton = ({ type, onPressOut }) => {
return (
);
};IconButton.propTypes = {
// PropTypes.oneOf: ์ด๊ฑฐํ(enum)์ผ๋ก ์ฒ๋ฆฌํ์ฌ prop๊ฐ ํน์ ๊ฐ๋ค๋ก ์ ํ๋๋๋ก ํ ์ ์์ต๋๋ค.
type: PropTypes.oneOf(Object.values(images)).isRequired,
onPressOut: PropTypes.func,
}
```
## ๐จ๐ปโ๐ป ThemeProvider
- ๋ชจ๋ ์ปดํฌ๋ํธ๋ฅผ ๊ฐ์ธ๋ ์ต์์ ์ปดํฌ๋ํธ๋ก ThemeProvider ์ปดํฌ๋ํธ๋ฅผ ์ฌ์ฉํ๋ฉฐ, ThemeProvider ์ปดํฌ๋ํธ์ theme ์์ฑ์ ์์์ ์ ์ํ ์์ ์ค์ ํ๋ฉด, ThemeProvider ์ปดํฌ๋ํธ์ ์์ ์ปดํฌ๋ํธ์์๋ ์คํ์ผ๋ ์ปดํฌ๋ํธ๋ฅผ ์ด์ฉํ ๋, props๋ก theme๋ฅผ ์ ๋ฌ๋ฐ์ ์ด์ฉํ ์ ์๋ค.```javascript
(...)
```
## ๐จ๐ปโ๐ป CRUD ๋ฉ์๋ ๊ตฌํ
### ๐ _addTask
```javascript
const _addTask = () => {
const ID = Date.now().toString();
const newTaskObject = {
[ID]: { id: ID, text: newTask, completed: false},
}
alert(`Add: ${newTask}`);
setNewTask('');
setTasks({...tasks, ...newTaskObject});
};
```
### ๐ _deleteTask
```javascript
const _deleteTask = id => {
// Object.assign ๋ฉ์๋๋ ์ด๊ฑฐํ ์ ์๋ ํ๋ ์ด์์ ์ถ์ฒ ๊ฐ์ฒด๋ก๋ถํฐ ๋์ ๊ฐ์ฒด๋ก ์์ฑ์ ๋ณต์ฌํ ๋ ์ฌ์ฉ
const currentTasks = Object.assign({}, tasks);
delete currentTasks[id];
setTasks(currentTasks);
};
```
### ๐ _toggleTask
```javascript
const _toggleTask = id => {
const currentTasks = Object.assign({}, tasks);
currentTasks[id]['completed'] = !currentTasks[id]['completed'];
setTasks(currentTasks);
};
```
### ๐ _updateTask
```javascript
const _updateTask = item => {
const currentTasks = Object.assign({}, tasks);
currentTasks[item.id] = item;
setTasks(currentTasks);
}
```
## ๐จ๐ปโ๐ป ๋ถ๊ฐ ๊ธฐ๋ฅ
### ๐ AsyncStorage
- ๋ฆฌ์กํธ ๋ค์ดํฐ๋ธ์์๋ AsyncStorage๋ฅผ ์ด์ฉํด ๋ก์ปฌ์ ๋ฐ์ดํฐ๋ฅผ ์ ์ฅํ๊ณ ๋ถ๋ฌ์ค๋ ๊ธฐ๋ฅ์ ๊ตฌํํ ์ ์๋ค.
- AsyncStorage๋ ๋น๋๊ธฐ๋ก ๋์ํ๋ฉฐ ๋ฌธ์์ด๋ก ๋ ํค-๊ฐ(Key-Value) ํํ์ ๋ฐ์ดํฐ๋ฅผ ๊ธฐ๊ธฐ์ ์ ์ฅํ๊ณ ๋ถ๋ฌ์ฌ ์ ์๋ ๊ธฐ๋ฅ์ ์ ๊ณตํ๋ค.
- expo install์ npm install๊ณผ ๊ฑฐ์ ๋์ผํ ์ญํ ์ ํ๋ค. ์ฐจ์ด์ ์ ์ฌ์ฉ์ค์ธ Expo SDK ๋ฒ์ ๊ณผ ํธํ๋๋ ๋ฒ์ ์ด ์๋์ง ํ์ธํ๊ณ , ํด๋น ๋ฒ์ ์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ค์นํ๋ ๊ณผ์ ์ด ์ถ๊ฐ๋์๋ค.```javascript
//intall ์์ ์
expo install @react-native-community/async-storage//install ์์ ํ
expo install @react-native-async-storage/async-storage//import
import AsyncStorage from '@react-native-async-storage/async-storage';//๋ฐ์ดํฐ ๋ด๊ธฐ
const _saveTasks = async tasks => {
try {
await AsyncStorage.setItem('tasks', JSON.stringify(tasks));
setTasks(tasks);
} catch (e) {
console.error(e);
}
}//๋ฐ์ดํฐ ๋ถ๋ฌ์ค๊ธฐ
const _loadTasks = async () => {
const loadedTasks = await AsyncStorage.getItem('tasks');
setTasks(JSON.parse(loadedTasks || {}));
};
```
### ๐ AppLoading
- AppLoading ์ปดํฌ๋ํธ๋ ํน์ ์กฐ๊ฑด์์ ๋ก๋ฉ ํ๋ฉด์ด ์ ์ง๋๋๋ก ํ๋ ๊ธฐ๋ฅ์ผ๋ก, ๋ ๋๋ง ํ๊ธฐ ์ ์ ์ฒ๋ฆฌํด์ผ ํ๋ ์์ ์ ์ํํ๋ ๋ฐ ์ ์ฉํ๊ฒ ์ฌ์ฉ๋๋ค.
1. startAsync: AppLoading ์ปดํฌ๋ํธ๊ฐ ๋์ํ๋ ๋์ ์คํ ๋ ํจ์
2. onFinish: startAsync๊ฐ ์๋ฃ๋๋ฉด ์คํํ ํจ์
3. onError: startAsync์์ ์ค๋ฅ๊ฐ ๋ฐ์ํ๋ฉด ์คํํ ํจ์```javascript
//install
expo install expo-app-loading//import
import AppLoading from 'expo-app-loading';//AppLoading ์์
setIsReady(true)}
onError={console.error}
/>
```
### ๐ app.json
- ๋ก๋ฉ ํ๋ฉด, ์์ด์ฝ์ app.json์์ ๋ฐ๊ฟ ์ ์๋ค.
- ๋ก๋ฉ ํ๋ฉด์ผ๋ก ์ฌ์ฉ ๋ ์ด๋ฏธ์ง์ ํฌ๊ธฐ๋ ๋ค์ํ ๊ธฐ๊ธฐ์ ๋์ํ๊ธฐ ์ํด 1242 x 2436์ผ๋ก ์ค๋นํ๋ ๊ฒ์ด ์ข๋ค.
- ๋ก๋ฉ ํ๋ฉด์์ ๊ธฐ๊ธฐ์ ํฌ๊ธฐ์ ๋ฐ๋ผ ๊ณต๋ฐฑ์ด ์๊ธฐ๋ ๊ฒฝ์ฐ, resizeMode์ ๊ฐ์ cover๋ก ๋ณ๊ฒฝํ๊ฑฐ๋, backgroundColor์ ๊ฐ์ ๋ณ๊ฒฝํ๋ฉด ๋๋ค.
- ์์ด์ฝ์ผ๋ก ์ฌ์ฉ ๋ ์ด๋ฏธ์ง๋ iOS์ ๊ฒฝ์ฐ 1024 x 1024 ํฌ๊ธฐ๊ฐ ํ์ํ๊ณ ์๋๋ก์ด๋์ ๊ฒฝ์ฐ 512 x 512ํฌ๊ธฐ์ ์ด๋ฏธ์ง๊ฐ ํ์ํ๋ฏ๋ก, ์ฌ๋งํ๋ฉด 1024 x 1024 ํฌ๊ธฐ์ ์ด๋ฏธ์ง๋ฅผ ์ฌ์ฉํ๋๊ฒ ์ข๋ค.```json
{
"expo": {
//(...์๋ต)
"icon": "./assets/splash.png",
"splash": {
"image": "./assets/splash.png",
"resizeMode": "contain",
"backgroundColor": "#ffffff"
},
//(...์๋ต)
"android": {
"adaptiveIcon": {
"foregroundImage": "./assets/splash.png",
"backgroundColor": "#FFFFFF"
}
},
//(...์๋ต)
}
}
```