Todo-list 프로젝트 회고록

Hanjinsu·2023년 6월 1일
0

코딩온X포스코

목록 보기
19/19

1. 프로젝트

1-1.프로젝트 설명

이번에 만들어 본 프로젝트는 내가 할일을 기록하고 수행여부를 체크 할 수 있는 TODO-list 웹 사이트를 만들어 보았다.

1-2.기간

2023월 4월 23 ~ 2023년 4월 29일

1-3.기술 스텍

  • React
  • Node.js
  • MySQL
  • HTML
  • CSS

1-4.파일구조


파일 구조는 client와 sever로 나누어서 작성을 해보았다.

2.실행화면

먼저 Node.js express프레임워크와 MySQL를 사용해백엔드애플리케이션 개발을 진행 하였다.

정보를 저장할 테이블을 먼저 만들어 주었다.

그리고 서버파일에 routes폴더에 경로를 설정해 주었다.

const express = require('express');
const router = express.Router();
const controller = require('../controller/Ctodo');

// GET /api/todos - show all todos (READ)
router.get('/todos', controller.readTodos);

// POST /api/todo - create a new todo (CREATE)
router.post('/todo', controller.createTodo);

// PATCH /api/todo/:todoId - edit a specific todo (UPDATE)
router.patch('/todo/:todoId', controller.updateTodo);

// DELETE /api/todo/:todoId - remove a specific todo (DELETE)
router.delete('/todo/:todoId', controller.deleteTodo);

module.exports = router;

controller 폴더에는 추가,수정,삭제 기능에 관련된 코드를 입력해 주었다.

const { Todo } = require("../models");
const { Op } = require("sequelize");

// GET /api/todos - show all todos (READ)
exports.readTodos = async (_, res) => {
  try {
    let todos = await Todo.findAll({ order: [["id", "DESC"]] });
    // select * from todo;

    //select * from todos order by id desc;
    res.send(todos);
  } catch (err) {
    res.send(err);
  }
};

// POST /api/todo - create a new todo (CREATE)
exports.createTodo = async (req, res) => {
  console.log(">>>>", req.body);
  try {
    let newTodo = await Todo.create({
      title: req.body.title,
      done: false, // todoItem 추가시 false가 기본 값
    });
    console.log(newTodo);
    res.send(newTodo);
  } catch (err) {
    res.send(err);
  }
};

// PATCH /api/todo/:todoId - edit a specific todo (UPDATE)
exports.updateTodo = async (req, res) => {
  console.log(req.body);
  try {
    // 배열 구조 분해
    // [isUpdated] = [ 0 ] or [ 1 ]
    let [idUpdated] = await Todo.update(
      {
        title: req.body.title,
        done: req.body.done,
      },
      {
        where: {
          id: { [Op.eq]: req.params.todoId },
        },
      }
    );
    // console.log(idUpdated); // 0 or 1

    // 수정 실패
    if (idUpdated === 0) {
      return res.send(false);
    }
    // 수정 성공
    res.send(true);
  } catch (err) {
    res.send(err);
  }
};
// Delect/api/todo/:todoId
exports.deleteTodo = async (req, res) => {
  try {
    let isDeleted = await Todo.destroy({
      where: {
        id: { [Op.eq]: req.params.todoId },
      },
      raw: true,
    });
    // console.log(isDeleted); // 0 or 1
    // 삭제 실패
    if (!isDeleted) {
      return res.send(false);
    }
    // 삭제 성공
    res.send(true);
  } catch (err) {
    res.send(err);
  }
};

다음은 client 프론트 개발 쪽에서 react 라이브러리를 사용하여 코드를 작성하였다.

APP.js

import { useState, useEffect } from "react";
import { REACT_APP_DB_HOST } from "./app-config";
import Todo from "./components/Todo";
import AddTodo from "./components/AddTodo";
import axios from "axios";
import "./styles/_utils.scss";
import "./styles/App.scss";

console.log(process.env.REACT_APP_DB_HOST);

function App() {
  const [todoItems, setTodoItems] = useState([]);

  useEffect(() => {
    console.log("mount완료");
    const getTodos = async () => {
      const res = await axios.get(`${process.env.REACT_APP_DB_HOST}/api/todos`);
      console.log()
      setTodoItems(res.data);
    };
    console.log('getTodos 선언')

    getTodos();
    console.log('getTodos 실행')
    console.log(todoItems)
  }, []);

  // Todo 추가하는 함수
  const addItem = async (newItem) => {
    // newItem => { title: 'xxx' }
    newItem.id = todoItems.length + 1;
    newItem.done = false;
    // newItem => { title: 'xxx', id: n, done: false }

    // setTodoItems([...todoItems, newItem]);

    //============sever axios 데이터 날리기
    const res = await axios.post(`${process.env.REACT_APP_DB_HOST}/api/todo`, newItem);
    console.log(res.data);
    setTodoItems([newItem, ...todoItems]);
    console.log(process.env.REACT_APP_DB_HOST)
  };

  // Todo 삭제하는 함수
  const deleteItem = async (targetItem) => {
    // targetItem => { title: 'xxx', id: n, done: false }
    // 1. filter()
    // : targetItem의 id 와 todoItems state의 id가 같지 않은 애들을 새로운 배열로 반환
    // const newTodoItems = todoItems.filter((item) => item.id !== targetItem.id);
    // 2. state 변경
    // setTodoItems(newTodoItems);
    //===========sever axios 데이터 지우기
    await axios.delete(`${process.env.REACT_APP_DB_HOST}/api/todo/${targetItem.id}`);
    const newTodoItems = todoItems.filter((item) => item.id !== targetItem.id);
    setTodoItems(newTodoItems);
    console.log(process.env.REACT_APP_DB_HOST)
  };
  //Todo 수정하는 함수
  // (1)server API를 이용해 db데이터를 업데이트
  // (2)변경된 내용을 화면에 다시 출력
  const updateItem = async (targetItem) => {
    console.log(targetItem); // {id: n, title: 'xxx', done: false }
    await axios.patch(`${process.env.REACT_APP_DB_HOST}/api/todo/${targetItem.id}`, targetItem);
    // 서버에서 수정이 완료된 후에도 취소선이 유지되도록 state 업데이트
    const updatedTodoItems = todoItems.map((item) => {
      if (item.id === targetItem.id) {
        return { ...item, done: targetItem.done };
      } else {
        return item;
      }
    });
    setTodoItems(updatedTodoItems);
    console.log(process.env.REACT_APP_DB_HOST)
  };

  return (
    <div className="App">
      <h1>Todo-List</h1>
      {/* todo 추가 input */}
      {/* <AddTodo addItem={{ addItem }} /> */}

      {/* <div className="left-todos">x

      {/* <div className="left-todos">😜 {todoItems.length} Todos</div> */}

      {/* todo 목록 보이기 */}
      {console.log('hi', todoItems)}
      {todoItems.map((item) => {
        console.log(item)
        return (
          <Todo
            key={item.id}
            item={item}
            deleteItem={deleteItem}
            updateItem={updateItem}
          />
        );
      })}
      <br />
      <AddTodo addItem={addItem} />
    </div>
  );
}

export default App;

프론트쪽의 app.js파일이다. 이곳에서 sever API를 이용하여 요청을 보내고 db 데이터를 업데이트 할 수 있도록 연결 해주었다.

0개의 댓글