유저가 submit 버튼 누르는걸 감지하도록 만들어볼거다.
이때 사용하는 props가 onSubmitEditing이다.
버튼이 눌렸다면 addToDo 함수가 실행될거고
이때 text가 비어있으면 리턴해주고 그게 아니라면 setText를 통해 todo를 save해줄것이다.
이제 toDos를 담아놓기 위해 useState를 만들어줄 것인데 Object로 만들어줄 것이다. hashMap처럼!
toDo 리스트를 쓰다보면 이전 toDos와 새로운 toDo를 합쳐야 할 때가 생기는데 이때 사용하는 것이 object Assign이다!
object Assign
object을 가져다가 다른 object와 합쳐준다. 그런다음 새로운 object를 리턴한다.
약간 js에서 스프레드 연산자 생각하면 될듯하다.
Object.asssingn(target,source) 꼴이다.
target은 보통 새로 만들어질 object가 들어가고
source에는 이전 object와 새로 만드는 object에 들어갈 애들이 위치한다.
위 코드에서 target은 새로 만들어질 object -->{}
source는 이전 toDo와 newToDo이다.
key는 Date.now()로 해서 고유 id값을 설정해준다. -> 왜 이런것을 하는지 궁금할 수 도 있는데 toDo를 구별해주어서
나중에 투두리스트에 삽입하거나 삭제할 때 용이하게 하기 위함이다.
value에는 text와 work의 todo인지 아닌지 넣어준다.
여기서 핵심은 기존의 todo를 변형시키지 않고 새로운 todo를 만드는 것이다.
그리고 newToDos를 setToDos안에 넣어줌으로써 저장한다.
ES6마법
Object Assign이 이해되지 않는다면 ES6의 마법을 사용하면 된다.
우선 새로운 Object를 만들고 그 안에 todo 내용을 적으면 된다.
const newToDos={...toDos}에서 ...을 통해 이전의 toDos를 받아온다! 그래야 합쳐질 수 있다.
합쳐진 Object를 어떻게 나열하지? ->Object.keys()
배열에서는 map을 통해 item을 빼서 나열했는데 object에서는 어떻게 할까?
Objcet.key(Object)를 하면 object key들의 array를 보여준다.
이제 key를 가진 배열을 가졌으니 map을 쓸 수 있다!!
여기서 toDos[key]를 하면 각 key의 내용을 얻게 된다.
toDos[key].text 하면 text 내용
toDos[key].work 하면 지금 work인지 travel인지도 알 수 있다.
최종코드
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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
|
import { StatusBar } from 'expo-status-bar';
import { StyleSheet, Text, View,TouchableOpacity,
TouchableHighlight,TouchableWithoutFeedback,TextInput,ScrollView } from 'react-native';
import React, { useState } from "react";
import { WebView } from 'react-native-webview';
import { theme } from './colors';
export default function App() {
const[working,setWorking]=useState(true);
const [text,setText]=useState("");
const[toDos,setToDos]=useState({});
const travel=()=>setWorking(false);
const work=()=>setWorking(true);
const onChangeText=(payload)=>setText(payload);
const addToDo=()=>{
if(text===""){
return;
}
const newToDos={...toDos,[Date.now()]:{text,work:working}}
setToDos(newToDos);
//save to do
setText(text);
}
return (
<View style={styles.container}>
<StatusBar style="auto" />
<View style={styles.header}>
<TouchableOpacity onPress={work}>
<Text style={{...styles.btnText,color:working? "white":theme.grey}}>Work</Text>
</TouchableOpacity>
<TouchableOpacity onPress={travel}
>
<Text style={{...styles.btnText,color:!working?"white":theme.grey}}>Travel</Text>
</TouchableOpacity>
</View>
<View>
<TextInput
onSubmitEditing={addToDo}
onChangeText={onChangeText}
returnKeyType='done'
placeholder={working?"Add a To Do":"Where do you want to go?"}
style={styles.input}/>
<ScrollView>
{Object.keys(toDos).map((key)=>
<View key={key} style={styles.toDo}>
<Text style={styles.toDoText}>{toDos[key].text}</Text>
</View>)}
</ScrollView>
</View>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: theme.bg,
paddingHorizontal:20,
},
header:{
justifyContent:"space-between",
flexDirection:"row",
marginTop:100,
},
btnText:{
fontSize:38,
fontWeight:"600",
},
input:{
backgroundColor:"white",
paddingVertical:15,
paddingHorizontal:20,
borderRadius:30,
marginVertical:20,
fontSize:18,
},
toDo:{
marginBottom:10,
paddingVertical:20,
paddingHorizontal:40,
backgroundColor:theme.grey,
borderRadius:15,
},
toDoText:{
color:"white",
fontSize:16,
fontWeight:"500",
},
});
|
cs |
'React Native' 카테고리의 다른 글
[RN] 투두리스트 코드챌린지 (0) | 2022.05.21 |
---|---|
[RN] 투두 리스트를 만들어보자! (2) (0) | 2022.05.21 |
[RN] TextInput (0) | 2022.05.21 |
[RN] TODO APP - 헤더 만들기 (0) | 2022.05.20 |
[RN] WeatherApp 만들기 - Icons 사용하기 (0) | 2022.05.14 |
댓글