이제 리액트 네이티브로 만든 투두리스트의 모든 기능을 구현할 차례이다. 솔직히 말하면 수정기능빼고 스스로 모두 구현했다. 사실 시간만 더 있으면 수정기능도 하려고 했는데, 튜터님의 강의를 보고 하는게 더 깔끔해보여서 일부러 기다렸다 ㅎㅎㅎ . 그결과 리액트 네이티브로도 투두리스트를 완성할 수 있었고, 튜터님의 코드기술을 보고 예상외의 방법으로도 전개가 가능한것을 알게 되어좋았다. 그리고 여러가지 궁금한점과 예외가능성에 대해서 질문하고 답변받는 시간도 있었다.
코드는 아래와 같으며 꽤 길다 ~~~
import { StatusBar } from "expo-status-bar";
import {
Alert,
SafeAreaView,
ScrollView,
StyleSheet,
Text,
TextInput,
TouchableOpacity,
View,
} from "react-native";
import { AntDesign } from "@expo/vector-icons";
import React, { useEffect, useState } from "react";
import uuid from "react-uuid";
import AsyncStorage from "@react-native-async-storage/async-storage";
export default function App() {
const [todos, setTodos] = useState([]);
const [category, setCategory] = useState("");
const [text, setText] = useState("");
const [edittext, setEdittext] = useState("");
const newTodo = {
id: uuid(),
text,
isDone: false,
isEdit: false,
category,
};
const addTodo = () => {
setTodos((prev) => [...prev, newTodo]);
setText("");
};
const setDone = (id) => {
const newTodos = [...todos];
const idx = newTodos.findIndex((todo) => todo.id === id);
newTodos[idx].isDone = !newTodos[idx].isDone;
setTodos(newTodos);
};
const editTodo = (id) => {
const newTodos = [...todos];
const idx = newTodos.findIndex((todo) => todo.id === id);
newTodos[idx].isEdit = !newTodos[idx].isEdit;
setTodos(newTodos);
};
const setEdit = (id) => {
const newTodos = [...todos];
const idx = newTodos.findIndex((todo) => todo.id === id);
newTodos[idx].text = edittext;
newTodos[idx].isEdit = false;
setTodos(newTodos);
setEdittext("");
};
const deleteTodo = (id) => {
Alert.alert("Todo 삭제", "정말로 삭제하시겠습니까?", [
{
text: "취소",
style: "cancel",
onPress: () => {},
},
{
text: "삭제",
styles: "destructive",
onPress: () => {
const newTodos = todos.filter((todo) => todo.id !== id);
setTodos(newTodos);
},
},
]);
};
const setCat = async (cat) => {
setCategory(cat);
await AsyncStorage.setItem("category", cat);
};
useEffect(() => {
const saveTodos = async () => {
await AsyncStorage.setItem("todos", JSON.stringify(todos));
};
if (todos.length > 0) saveTodos();
}, [todos]);
useEffect(() => {
const getData = async () => {
const resp_todos = await AsyncStorage.getItem("todos");
const resp_category = await AsyncStorage.getItem("category");
setTodos(JSON.parse(resp_todos));
setCategory(resp_category ?? "js");
};
getData();
}, []);
return (
<SafeAreaView style={{ flex: 1 }}>
<View style={styles.container}>
<StatusBar style="auto" />
<View style={styles.topbox}>
<View style={styles.buttonbar}>
<TouchableOpacity
onPress={() => setCat("js")}
style={{
...styles.button,
backgroundColor: category === "js" ? "#26a4e3" : "gray",
}}
>
<Text>Javascript</Text>
</TouchableOpacity>
<TouchableOpacity
onPress={() => setCat("react")}
style={{
...styles.button,
backgroundColor: category === "react" ? "#26a4e3" : "gray",
}}
>
<Text>React</Text>
</TouchableOpacity>
<TouchableOpacity
onPress={() => setCat("ct")}
style={{
...styles.button,
backgroundColor: category === "ct" ? "#26a4e3" : "gray",
}}
>
<Text>Coding Test</Text>
</TouchableOpacity>
</View>
<View style={{ borderTopWidth: 1, marginTop: 10 }}></View>
<TextInput
style={styles.input}
onChangeText={setText}
value={text}
placeholder="Enter your task"
onSubmitEditing={addTodo}
/>
<View style={{ borderTopWidth: 1, marginTop: 15 }}></View>
</View>
<View>
<ScrollView>
{todos.map((todo) => {
if (category === todo.category) {
return (
<View key={todo.id} style={styles.todo}>
{todo.isEdit == true ? (
<TextInput
style={{ flex: 1, backgroundColor: "white" }}
onChangeText={setEdittext}
value={edittext}
onSubmitEditing={() => {
setEdit(todo.id);
}}
/>
) : (
<Text
style={{
textDecorationLine: todo.isDone
? "line-through"
: "none",
}}
>
{todo.text}
</Text>
)}
<View style={{ flexDirection: "row" }}>
<AntDesign
style={{ marginLeft: 10 }}
name="checksquare"
size={24}
onPress={() => {
setDone(todo.id);
}}
/>
<AntDesign
style={{ marginLeft: 10 }}
name="form"
size={24}
color="black"
onPress={() => {
editTodo(todo.id);
}}
/>
<AntDesign
style={{ marginLeft: 10 }}
name="delete"
size={24}
color="black"
onPress={() => {
deleteTodo(todo.id);
}}
/>
</View>
</View>
);
}
})}
</ScrollView>
</View>
</View>
</SafeAreaView>
);
}
const styles = StyleSheet.create({
container: {
margin: 30,
flex: 1,
},
topbox: {
marginTop: 15,
},
buttonbar: {
flexDirection: "row",
justifyContent: "space-between",
textAlign: "center",
},
button: {
width: 95,
height: 40,
backgroundColor: "gray",
justifyContent: "center",
alignItems: "center",
},
input: {
height: 40,
marginTop: 12,
borderWidth: 1,
padding: 10,
},
todo: {
justifyContent: "space-between",
marginTop: 15,
flexDirection: "row",
backgroundColor: "#cccccc",
padding: 10,
alignItems: "center",
},
});
사실 CURD 기능외에도 AsyncStorage기능을 통해 새로고침을 해도 기존 데이터가 그대로 유지되는 법도 배웠다. 이제 남은건 firebase 혹은 json서버등을 이용하여 , 온라인환경에서도 제대로 구현이 되냐는 것이다.
일단 오늘까지 있었던 알고리즘문제는 모두다 풀었기에, 이제 firebase를 이용하여 앱을 배포하고 한번 사용해볼 기회가 생겼다. 그리고 시간이 더 주어진다면 이렇게 위처럼 길게 풀어쓴 코드를 컴포넌트를 나눠서 쓰려고 한다 ㅎㅎ
이제 내일이면 올해의 마지막인데, 사실 10월부터 지금까지 대단히 빠르게 왔다. 앞으로는 어떤일이 일어날지 궁금하지만 , 좋은일만 생길거라고 왠지 모를 예측이 된다ㅎㅎㅎ
'스파르타 기간 동안의 TIL' 카테고리의 다른 글
오늘의 공부를 끝내며.. (1/2) (0) | 2023.01.02 |
---|---|
9주차 WIL (2) | 2023.01.01 |
오늘의 공부를 끝내며.. (12/29) (0) | 2022.12.29 |
오늘의 공부를 끝내며.. (12/28) (0) | 2022.12.28 |
오늘의 공부를 끝내며.. (12/27) (0) | 2022.12.27 |