스파르타 기간 동안의 TIL

오늘의 공부를 끝내며.. (1/2)

푸른매실 2023. 1. 2. 20:57

새해의 시작은 스타트가 좋다. 파이어베이스를 통해 데이터 CURD에 성공했고, 거의 잘 다룰수 있게 되었다. ㅎㅎ 

아래에 간결하게 코드를 남기면 (app.js만~)

 

import { StatusBar } from "expo-status-bar";
import {
  Alert,
  SafeAreaView,
  ScrollView,
  StyleSheet,
  Text,
  TextInput,
  TouchableOpacity,
  View,
} from "react-native";
import {
  onSnapshot,
  query,
  collection,
  doc,
  orderBy,
  addDoc,
  getDoc,
  getDocs,
  updateDoc,
  deleteDoc,
} from "firebase/firestore";
import { dbService } from "./firebase";

import React, { useEffect, useState } from "react";
import uuid from "react-uuid";
import AsyncStorage from "@react-native-async-storage/async-storage";
import { AntDesign } from "@expo/vector-icons";
import ButtonBar from "./components/ButtonBar";
import Todo from "./components/Todo";
import { async } from "@firebase/util";

export default function App() {
  const [todos, setTodos] = useState([]);
  const [category, setCategory] = useState("");
  const [text, setText] = useState("");
  const [edittext, setEdittext] = useState("");

  const newTodo = {
    text,
    isDone: false,
    isEdit: false,
    category,
    createdAt: Date.now(),
  };

  const addTodo = async () => {
    // setTodos((prev) => [...prev, newTodo]);
    await addDoc(collection(dbService, "todos"), newTodo); // collection안으로 객체( doc.data() ) 추가 이 때 doc.id는 자동으로 생성됨
    setText("");
  };

  const setDone = async (id) => {
    // const newTodos = [...todos];
    const idx = todos.findIndex((todo) => todo.id === id);
    // newTodos[idx].isDone = !newTodos[idx].isDone;

    await updateDoc(doc(dbService, "todos", id), {
      isDone: !todos[idx].isDone,
    }); // doc 지정 후 변경할 속성 및 값 지정

    // setTodos(newTodos);
  };

  const editTodo = async (id) => {
    // const newTodos = [...todos];
    const idx = todos.findIndex((todo) => todo.id === id);
    // newTodos[idx].isEdit = !newTodos[idx].isEdit;
    await updateDoc(doc(dbService, "todos", id), {
      isEdit: !todos[idx].isEdit,
    }); // doc 지정 후 변경할 속성 및 값 지정

    // setTodos(newTodos);
  };

  const setEdit = async (id) => {
    // const newTodos = [...todos];
    // const idx = newTodos.findIndex((todo) => todo.id === id);
    // newTodos[idx].text = edittext;
    // newTodos[idx].isEdit = false;

    await updateDoc(doc(dbService, "todos", id), {
      text: edittext,
      isEdit: false,
    }); // doc 지정 후 변경할 속성 및 값 지정

    setEdittext("");
  };

  const deleteTodo = (id) => {
    Alert.alert("Todo 삭제", "정말로 삭제하시겠습니까?", [
      {
        text: "취소",
        style: "cancel",
        onPress: () => {},
      },
      {
        text: "삭제",
        styles: "destructive",
        onPress: async () => {
          // const newTodos = todos.filter((todo) => todo.id !== id);
          await deleteDoc(doc(dbService, "todos", id)); // 해당 doc 를 삭제
          // setTodos(newTodos);
        },
      },
    ]);
  };

  const setCat = async (cat) => {
    setCategory(cat);
    // await AsyncStorage.setItem("category", cat);
    await updateDoc(doc(dbService, "category", "currentCategory"), {
      category: cat,
    }); // doc 지정 후 변경할 속성 및 값 지정
  };

  // useEffect(() => {
  //   const saveTodos = async () => {
  //     await AsyncStorage.setItem("todos", JSON.stringify(todos));
  //   };
  //   if (todos.length > 0) saveTodos();
  // }, [todos]);

  useEffect(() => {
    // const resp_todos = await AsyncStorage.getItem("todos");
    // const resp_category = await AsyncStorage.getItem("category");
    // setTodos(JSON.parse(resp_todos));
    // setCategory(resp_category ?? "js");
    const q = query(
      collection(dbService, "todos"),
      orderBy("createdAt", "desc") // 해당 collection 내의 docs들을 createdAt 속성을 내림차순 기준으로
    );

    onSnapshot(q, (snapshot) => {
      // q (쿼리)안에 담긴 collection 내의 변화가 생길 때 마다 매번 실행됨
      const newTodos = snapshot.docs.map((doc) => {
        const newTodo = {
          id: doc.id,
          ...doc.data(), // doc.data() : { text, createdAt, ...  }
        };
        return newTodo;
      });
      setTodos(newTodos);
    });

    const getCategory = async () => {
      const snapshot = await getDoc(
        doc(dbService, "category", "currentCategory")
      ); // 하나의 doc를 가져옴.
      setCategory(snapshot.data().category);
    };
    getCategory();
  }, []);

  return (
    <SafeAreaView style={{ flex: 1 }}>
      <View style={styles.container}>
        <StatusBar style="auto" />
        <View style={styles.topbox}>
          <ButtonBar setCat={setCat} category={category} />

          <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 (
                  <Todo
                    todo={todo}
                    key={todo.id}
                    setEdittext={setEdittext}
                    edittext={edittext}
                    setEdit={setEdit}
                    setDone={setDone}
                    editTodo={editTodo}
                    deleteTodo={deleteTodo}
                  />
                );
              }
            })}
          </ScrollView>
        </View>
      </View>
    </SafeAreaView>
  );
}

const styles = StyleSheet.create({
  container: {
    margin: 30,
    flex: 1,
  },
  topbox: {
    marginTop: 15,
  },

  input: {
    height: 40,
    marginTop: 12,
    borderWidth: 1,
    padding: 10,
  },
});
 
 

컴포넌트화를 통해서 조금 쪼개긴했는데, 그래도 길긴하다 ㅋㅋㅋ 그리고 오늘 리액트 네이티브 파이어베이스 과정후에

나의 선택으로 앱개발강의를 다시 강의를 듣게 되었는데, 강의내용이 쏙쏙들어온다. 확실히 아무것도 모르는 상태랑 어느정도 네이티브에 익숙한 상태에서 앱개발강의를 듣는건 천지차이인거 같다. 그래서 앱개발강의도 무사히 잘 해내고 있고, 이전에 평점을 낮게 준 부분에 대해서도 충분히 이해가 간다. 확실히 백지상태에서 앱개발강의를 듣는다면 매우 어려울것이다. 그러기에 지금이 제일 듣기가 좋고 한 주차씩 잘 해내고 있다. 올 해도 개발자로써의 품격과 실력을 다지기를 다짐한다 !!