10. TODO APP (UPDATE - STATUS)

Todo APP 을 만들어봅니다

들어가기전

이번 챕터에서는 isDone 이라고 불리는 Todo 의 완료여부를 나타내는 값을 업데이트 해보겠습니다.

실습

따로 스타일이 없기 때문에 isDone 이 true 인 경우 text 옆 쪽에 (완료) 라는 문구를 추가해보겠습니다. 이 또한 추가, 삭제와 비슷한 패턴입니다. event 는 Contents 에서 일어나고 실제 데이터를 변화시키는 곳은 App.js 입니다.

먼저 App.js 의 함수를 추가해보겠습니다.

import React, { useState } from "react";

import Header from "./components/header";
import Contents from "./components/contents";
import Footer from "./components/footer";

function App() {
  const [todos, setTodos] = useState([]);

  const handleAdd = text => {
    setTodos([
      ...todos,
      {
        id: Date.now(),
        text,
        isDone: false
      }
    ]);
  };

  const handleDelete = id => {
    setTodos(todos.filter(todo => todo.id !== id));
  };

  const handleUpdateStatus = id => { // isDone 을 업데이트 하는 함수를 추가합니다.
    setTodos(
      todos.map(todo =>
        todo.id === id ? { ...todo, isDone: !todo.isDone } : todo
      )
    );
  };

  return (
    <div>
      <Header onChange={handleAdd} />
      <Contents
        todos={todos}
        onDelete={handleDelete}
        onUpdateStatus={handleUpdateStatus}
      />
      <Footer />
    </div>
  );
}

export default App;

handleUpdateStatus 함수의 문법이 익숙하지 않을 수도 있기 때문에 한번 살펴보고 넘어가겠습니다.

map => 기존 배열을 통해 새로운 배열을 만들어내는 함수 id 비교 => 넘겨 받은 id 와 기존 todo list 에 있는 id 와 비교합니다. id 가 같다면 => { ...todo } 를 이용하여 기존 객체를 복사합니다. 그리고 { ...todo, isDone: !todo.isDone } 을 이용하여 기존 객체의 isDone 을 한번 뒤집어 토글해준 값으로 덮어씌웁니다. id 가 다르다면 => 아무런 변화도 주지 않습니다.

todos.map(todo =>
  todo.id === id ? { ...todo, isDone: !todo.isDone } : todo
)

update isDone

이제 Contents 에서 넘겨받은 함수를 이용하여 상태를 업데이트 해보겠습니다. isDone 에 따른 문구 추가와 checkbox 에 onChange 함수를 추가해야합니다.

// src/components/contents.js

import React from "react";

function Todo({ todo: { id, text, isDone }, onDelete, onUpdateStatus }) {
  return (
    <div>
      <input
        type="checkbox"
        onChange={() => onUpdateStatus(id)}
        checked={isDone}
      />
      <span>
        {text} {isDone ? "(완료)" : "(진행중)"}
      </span>
      <button onClick={() => onDelete(id)}>DELETE</button>
    </div>
  );
}

function Contents({ todos, onDelete, onUpdateStatus }) {
  return (
    <div>
      {todos.map(todo => (
        <Todo
          todo={todo}
          onDelete={onDelete}
          onUpdateStatus={onUpdateStatus}
          key={todo.id}
        />
      ))}
    </div>
  );
}

export default Contents;

Last updated