항해 15일차 (TodoList)

Undong·2023년 4월 18일
0

항해구구

목록 보기
15/52
post-thumbnail

항해 15일차 리액트 입문에서 공부한 걸 토대로 React TodoList를 만들어 보았다.

간략하게 보자면

TodoList

React 훅 useState와 props, jsx를 이용해서 간단히 만들어 보는 TodoList이다.

전체 코드를 보자면

import React, { useState } from "react";

function App() {
  const [users, setUser] = useState([
    { id: 1, title: "이동언", body: "나는 이동언이다.", isDone: false },
  ]);
  const [title, setTitle] = useState("");
  const [body, setBody] = useState("");

  const titlechange = (e) => {
    setTitle(e.target.value);
  };

  const bodychange = (e) => {
    setBody(e.target.value);
  };

  const addbtn = () => {
    // 추가 버튼
    const newUsers = {
      id: users.length + 1,
      title: title,
      body: body,
      isDone: false,
    };
    setUser([...users, newUsers]);
    setTitle("");
    setBody("");
  };

  const deletebtn = (id) => {
    // 삭제 버튼 id를 받아 id가 같지 않다며 제외한 배열 생성
    const delUser = users.filter((user) => user.id !== id);
    setUser(delUser);
  };

  const completebtn = (id) => {
    // 완료 버튼 id를 받아서 해당 id의 user의 isDone을 true로 변경
    const updatedUsers = users.map((user) =>
      user.id === id ? { ...user, isDone: !user.isDone } : user
    );
    setUser(updatedUsers);
  };

  const cancelbtn = (id) => {
    const updatedUsers = users.map((user) =>
      user.id === id ? { ...user, isDone: false } : user
    );
    setUser(updatedUsers);
  };

  return (
    <div className="최상단">
      <div>마이투두리스트</div>
      <div>리액트</div>
      <div>
        제목
        <input type="text" value={title} onChange={titlechange} />
        내용
        <input type="text" value={body} onChange={bodychange} />
      </div>
      <button onClick={addbtn}>추가하기</button>
      <div>
        <h2>Working</h2>
        {users
          .filter((user) => user.isDone === false)
          .map((user) => {
            return (
              <div>
                {user.title}-{user.body}
                <button onClick={() => deletebtn(user.id)}>삭제하기</button>
                <button onClick={() => completebtn(user.id)}>
                  {user.isDone ? "취소하기" : "완료하기"}
                </button>
              </div>
            );
          })}
      </div>
      <div>
        <h2>Done</h2>
        {users
          .filter((user) => user.isDone === true)
          .map((user) => {
            return (
              <div>
                {user.title}-{user.body}
                <button onClick={() => deletebtn(user.id)}>삭제하기</button>
                <button onClick={() => cancelbtn(user.id)}>
                  {user.isDone ? "취소하기" : "완료하기"}
                </button>
              </div>
            );
          })}
      </div>
    </div>
  );
}

export default App;

기능을 보자면

먼저

  const [users, setUser] = useState([
    { id: 1, title: "이동언", body: "나는 이동언이다.", isDone: false },
  ]);
  const [title, setTitle] = useState("");
  const [body, setBody] = useState("");

users는 todo에 등록된 항목들을 담는 것이다 각 항목에는 id, title, body, isDone의 속성을 가지고 있다.
또한 title과 body는 Todo 항목을 추가하기 위해 입력한 제목과 내용을 관리하는 것이다.

두 번째,

Todo 항목 추가이다.



  const addbtn = () => {
    // 추가 버튼
    const newUsers = {
      id: users.length + 1,
      title: title,
      body: body,
      isDone: false,
    };
    setUser([...users, newUsers]);
    setTitle("");
    setBody("");
  };

사용자가 입력한 제목과 내용을 가진 새로운 Todo 항목을 생성하고, users 배열에 추가하고, title, body 상태를 초기화한다.

세 번째,

Todo 항목 삭제이다.

const deletebtn = (id) => {
    // 삭제 버튼 id를 받아 id가 같지 않다며 제외한 배열 생성
    const delUser = users.filter((user) => user.id !== id);
    setUser(delUser);
  };

사용자가 선택한 항목을 users 배열에서 제거한다.

네 번째,

Todo 항목 완료 / 취소이다.

const completebtn = (id) => {
    // 완료 버튼 id를 받아서 해당 id의 user의 isDone을 true로 변경
    const updatedUsers = users.map((user) =>
      user.id === id ? { ...user, isDone: !user.isDone } : user
    );
    setUser(updatedUsers);
  };

  const cancelbtn = (id) => {
    const updatedUsers = users.map((user) =>
      user.id === id ? { ...user, isDone: false } : user
    );
    setUser(updatedUsers);
  };

사용자가 선택한 항목의 완료 상태(isDone)을 변경한다.
완료된 항목은 Done 영역에, 미완료된 항목은 Working 영역에 표시된다.
완료된 항목의 경우, 취소 버튼을 클릭하면 다시 미완료 사애태로 변경된다.

이렇게 추가, 삭제, 완료, 취소 등으로 TodoList를 구현하였다.

다 만든 후 components 별로 나누었다.

TodoItem, TodoList, App으로 컴포넌트를 분리하여 구성하였다.

import React from "react";

function TodoItem({ user, onDelete, onToggle }) {
  return (
    <div className="listbox">
      <h2>{user.title}</h2>
      <h3>{user.body}</h3>
      <div className="btnlist">
        <button className="delbtn btn " onClick={() => onDelete(user.id)}>
          삭제하기
        </button>
        <button className="donebtn btn" onClick={() => onToggle(user.id)}>
          {user.isDone ? "취소하기" : "완료하기"}
        </button>
      </div>
    </div>
  );
}

export default TodoItem;
import React from "react";
import TodoItem from "./TodoItem";

function TodoList({ title, users, onDelete, onToggle, isDone }) {
  return (
    <div className="list">
      <h2>{title}</h2>
      <div className="wrapper">
        {users
          .filter((user) => user.isDone === isDone)
          .map((user) => (
            <TodoItem
              key={user.id}
              user={user}
              onDelete={onDelete}
              onToggle={onToggle}
            />
          ))}
      </div>
    </div>
  );
}
export default TodoList;

마무리

todolist를 만들면서 isDone을 사용하여 완료, 취소하는 부분이 어려웠다. 다시 보고 검색도 하며 코드를 구현하여 뿌듯하였당 또한 컴포넌트 분리 기준을 알아보았고, 분리를 해보았다. 그래도 컴포넌트 분리는 계속 해봐야겠다.

profile
console.log("Hello")

0개의 댓글