Todo App v1

연성·2022년 3월 3일
0

Todo App

목록 보기
2/2
post-thumbnail

Todo App v0

  • HTML, CSS, Javascript만을 이용하여 Todo App을 만들었다.
  • 서버에서 데이터를 받아오는(척 하는) 어플리케이션으로 업그레이드 해보자.

추가된 기술

  • package.json
{
  "name": "todos-v1",
  "version": "1.0.0",
  "scripts": {
    "start": "nodemon backend/server"
  },
  "dependencies": {
    "axios": "^0.24.0",
    "express": "^4.17.3"
  },
  "devDependencies": {
    "nodemon": "^2.0.15",
    "eslint": "^8.5.0",
    "eslint-config-airbnb-base": "^15.0.0",
    "eslint-plugin-html": "^6.2.0",
    "eslint-plugin-import": "^2.25.3"
  }
}
  • axios, express, nodemon을 추가하여 서버와 통신하는 척 해보았다.
  • 대부분의 로직은 비슷하고 서버와 통신하는 코드만 추가하였다.
  • 서버는 요청을 보내면 응답으로 (변경된) todos 배열을 보내준다.

데이터 읽어오기

const fetchTodos = async () => {
  try {
    const { data: _todos } = await axios.get('/todos');
    setTodos(_todos);
  } catch (e) {
    console.error(e);
  }
};
  • axios 라이브러리를 사용하여 간단하게 구현하였다.
  • GET 요청으로 todos 배열을 받아온다.
  • v0과 마찬가지로 서버 통신을 통해 새로운 배열을 받아오면 항상 setTodos를 호출한다.

새로운 할 일 추가

const addTodo = async content => {
  try {
    const { data: _todos } = await axios.post('/todos', {
      id: getNextId(),
      content,
      completed: false,
    });
    setTodos(_todos);
  } catch (e) {
    console.error(e);
  }
};
  • POST 요청으로 새로운 할 일 객체를 보낸다.
  • 새로운 할 일이 추가된 todos배열을 받아 setTodos를 호출한다.

한 일 체크하기

const toggleCompleted = async id => {
  const { completed } = todos.find(todo => todo.id === +id);
  try {
    const { data: _todos } = await axios.patch(`/todos/${id}`, {
      completed: !completed,
    });
    setTodos(_todos);
  } catch (e) {
    console.error(e);
  }
};
  • PATCH 요청으로 completed를 변경한다.
  • url/todos/:id로 요청하고 완료 여부를 request body에 담아보낸다.

할 일 수정하기

const editTodo = async (id, content) => {
  try {
    const { data: _todos } = await axios.patch(`/todos/${id}`, { content });
    setTodos(_todos);
  } catch (e) {
    console.error(e);
  }
};
  • PATCH 요청으로 할 일 내용을 변경한다.
  • url은 한 일 체크하기와 같은 /todos/:id이고 내부 동작도 동일하다.
  • PATCH 내부
app.patch('/todos/:id', (req, res) => {
  const { id } = req.params;
  const payload = req.body;

  setTodos(
    todos.map(todo => (todo.id === +id ? { ...todo, ...payload } : todo))
  );
  res.send(todos);
});

할 일 삭제하기

const removeTodo = async id => {
  try {
    const { data: _todos } = await axios.delete(`/todos/${id}`);
    setTodos(_todos);
  } catch (e) {
    console.error(e);
  }
};
  • DELETE 요청으로 할 일을 삭제한다.
  • url/todos/:id이다.

리로드는 괜찮은데... 서버가 꺼지면?

  • express와 nodemon을 사용하여 todo 어플리케이션을 만들면 리로드를 해도 데이터가 남아있다.
  • 하지만 데이터를 express를 실행하는 js파일 내부에 기록하면 서버가 꺼졌을 때 해당 데이터가 초기화된다.
  • fs 모듈을 이용하여 외부 .json파일에 저장하는 방식을 사용하여 보았다.
let todos = JSON.parse(fs.readFileSync(`${__dirname}/data/todos.json`));

const setTodos = _todos => {
  todos = [..._todos];
  fs.writeFileSync(`${__dirname}/data/todos.json`, JSON.stringify(todos));
};
  • 서버에서 setTodo가 호출되면 현재 서버의 todos 배열을 변경하고 해당 내용을 외부의 todos.json에 기록한다.
  • 서버가 실행되면 todos.json 파일에서 데이터를 읽어오기 때문에 서버가 꺼져도 그 전의 기록이 남아있다.

개선하고 싶은 점

  • CSS...
  • 로컬의 .json이 아니라 실제 데이터베이스에 데이터를 올려서 데이터 통신을 해보고 싶다. (AWS, firebase 등...)
  • 최종은 리액트...

0개의 댓글