TIL #24 입문 과제 피드백

DO YEON KIM·2024년 5월 20일
0

부트캠프

목록 보기
24/72

하루 하나씩 작성하는 TIL #24

이전 피드백에서 파일을 세분화 할 필요성이 있다고 느껴 css는 제외하고 파일을 구조화 하였다.


기능과 역할 별로 그리고 반복적인 부분을 나누어보세요

  1. 투두 제출 폼(form)
  2. 투두 리스트
  3. 투두 아이템 카드

  • 하나의 투두는 여러 데이터를 가지고 있기 때문에 객체로서 만들어져야 해요.
    • 대표적으로는 투두 아이디, 제목, 내용, 완료 상태가 있겠죠?
  • 그리고 투두는 여러 개가 되어야 하므로 배열에 담아줘야 해요.
    • 결과적으로 객체 배열이 됩니다!

투두 데이터 구조 생각하기

  • 컨테이너 컴포넌트 파일 만들기
  • 투두 데이터를 저장할 상태를 선언하기
  • 만들어진 컨테이너 컴포넌트를 App.jsx에 붙여주기

투두 제출 컴포넌트 만들기

  • 투두 제출 폼 컴포넌트 파일 만들기
  • form 태그와 input 태그로 화면 구성하기
  • 폼 제출 이벤트 트리거용 button 태그 만들기
  • 폼 제출 이벤트를 통해 투두 추가하기

투두 리스트 컴포넌트 만들기

  • 투두 리스트 컴포넌트 파일 만들기
  • 컨테이너 컴포넌트로부터 투두 리스트 데이터를 props로 받아오기
  • 투두 아이템을 리스트 렌더링 해주기

투두 아이템 컴포넌트 만들기

  • 투두 아이템 컴포넌트 파일 만들기
  • 투두 리스트 컴포넌트로부터 투두 개별 데이터를 props로 받아오기
  • 받아온 props를 화면에 렌더링해주기

투두 이벤트 등록하기

TodoContainer의 데이터를 변경하는 이벤트를 등록합시다

  • 투두 아이템 컴포넌트에 삭제 버튼 추가하기
  • 삭제 버튼 클릭 이벤트를 통해 상태를 변화시켜 특정 투두 데이터 삭제하기
    • 특정 투두를 구별하기 위해서 id 를 사용하세요!
    • filter 메서드를 사용하세요!
  • 투두 아이템 컴포넌트에 완료 버튼 추가하기
  • 완료 버튼 클릭 이벤트를 통해 상태를 변화시켜 특정 투두 데이터 완료 상태 변경하기
    • 특정 투두를 구별하기 위해서 id 를 사용하세요!
    • map 메서드를 사용하세요!

yarn add react-router-dom
yarn create vite 폴더명 --template react
cd 폴더명
yarn
yarn dev

git init
git remote add origin 내 레포지 링크
git add .
git commit -m "커밋 메세지"
git push -u origin master

순으로 레포지에 틀을 올려주고 ,


src폴더 안에 components라는 폴더를 만들어주고, 그 안에

Layout.jsx

components안에 todo라는 폴더를 만들어주고, 그 안에

TodoContainer.jsx
TodoForm.jsx
TodoItem.jsx
Todolist.jsx
이렇게 4가지를 만들어 준다.


  • 단축어 rafce를 쓰면 기본적인 틀을 짜준다.

TodoContainer.jsx

import { useState } from "react";
import TodoForm from "./TodoForm";
import TodoList from "./TodoList";

const TodoContainer = () => {
  const [todos, setTodos] = useState([
    {
      id: 1,
      title: "할 일 1",
      content: "할 일 1 내용",
      isDone: false,
    },
  ]);
  //useState 훅을 사용하여 todos 상태와 setTodos 함수를 생성, 할일 목록을 관리

  const workingTodos = todos.filter((todo) => !todo.isDone);
  const doneTodos = todos.filter((todo) => todo.isDone);
  //todos 배열을 이용하여 작업 중인 할 일과 완료된 할 일 필터링, 할당.

  return (
    <section>
      <h1 className="title">Todo</h1>
      <TodoForm setTodos={setTodos} /> 
      <TodoList title="Working" todos={workingTodos} setTodos={setTodos} />
      <TodoList title="Done" todos={doneTodos} setTodos={setTodos} />
    </section>
  );
};

//<TodoForm> 컴포넌트를 렌더링. 
//이 컴포넌트에는 setTodos 함수가 props로 전달.
export default TodoContainer;

TodoForm.jsx

const TodoForm = ({ setTodos }) => {
  const onSubmit = (e) => {
    e.preventDefault();

    const formData = new FormData(e.target);
    const title = formData.get("title");
    const content = formData.get("content");

    if (!title.trim() || !content.trim())
      return alert("제목과 내용을 입력해주세요.");

    const nextTodo = {
      id: crypto.randomUUID(),
      title,
      content,
      isDone: false,
    };

    setTodos((prev) => [nextTodo, ...prev]);

    e.target.reset();
  };

  return (
    <div>
      <form onSubmit={onSubmit}>
        <input type="text" placeholder="제목" name="title" />
        <input type="text" placeholder="내용" name="content" />
        <button type="submit">추가</button>
      </form>
    </div>
  );
};

export default TodoForm;

TodoItem.jsx

const TodoItem = ({ todo, setTodos }) => {
  const { id, title, content, isDone } = todo;

  const deleteTodo = () => {
    setTodos((prev) => prev.filter((todo) => todo.id !== id));
  };

  const toggleTodo = () => {
    setTodos((prev) =>
      prev.map((todo) =>
        todo.id === id ? { ...todo, isDone: !todo.isDone } : todo
      )
    );
  };

  return (
    <div className="todo-card">
      <h3 className="todo-title">{title}</h3>
      <p>{content}</p>
      <div>
        <button onClick={toggleTodo}>{isDone ? "취소" : "완료"}</button>
        <button onClick={deleteTodo}>삭제</button>
      </div>
    </div>
  );
};

export default TodoItem;

Todolist.jsx

import TodoItem from "./TodoItem";

const TodoList = ({ title, todos, setTodos }) => {
  return (
    <div>
      <h2 className="todo-list-title">{title}</h2>
      <ul>
        {todos.map((todo) => (
          <li key={todo.id}>
            <TodoItem todo={todo} setTodos={setTodos} />
          </li>
        ))}
      </ul>
    </div>
  );
};

export default TodoList;

profile
프론트엔드 개발자를 향해서

0개의 댓글