스파르타 기간 동안의 TIL

오늘의 공부를 끝내며.. (12/30)

푸른매실 2022. 12. 30. 20:42

이제 리액트 네이티브로 만든 투두리스트의 모든 기능을 구현할 차례이다. 솔직히 말하면 수정기능빼고 스스로 모두 구현했다. 사실 시간만 더 있으면 수정기능도 하려고 했는데, 튜터님의 강의를 보고 하는게 더 깔끔해보여서 일부러 기다렸다 ㅎㅎㅎ . 그결과 리액트 네이티브로도 투두리스트를 완성할 수 있었고, 튜터님의 코드기술을 보고 예상외의 방법으로도 전개가 가능한것을 알게 되어좋았다. 그리고 여러가지 궁금한점과 예외가능성에 대해서 질문하고 답변받는 시간도 있었다. 

코드는 아래와 같으며 꽤 길다 ~~~

 

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월부터 지금까지 대단히 빠르게 왔다. 앞으로는 어떤일이 일어날지 궁금하지만 , 좋은일만 생길거라고 왠지 모를 예측이 된다ㅎㅎㅎ