행복을 담는 블로그

[TIL] 240123(화) React 입문 개인과제 : To-do list 만들기(1) 본문

TIL

[TIL] 240123(화) React 입문 개인과제 : To-do list 만들기(1)

hyun0zin 2024. 1. 23. 23:39

React 입문 강의가 끝나고 React 첫 개인과제도 끝이 났다.
이번 react 개인과제로 진행한 To-do List 만들기 에 대해서 리뷰해 보고자 한다.


📝 To-Do List 만들기

1. CRA 설치하기

npx create-react-app to-do-list프로젝트를 생성한다.


2. 기본 틀 잡기

처음에는 App.jsx 파일에서 기본 html을 구성하였다.

import React from "react";

function App() {

  /* card 기본 state */
  const todoObj = {
    id: 1,
    title: "리액트 공부하기",
    text: "리액트 기초를 공부해봅시다.",
    isDone: false,  
  };

  //구조분해 할당으로 객체 내부 key 값에 접근하기
  const { id, title, text, isDone } = todoObj;

  /* 기본적인 html 구조 만들기 */
  return (
    <div>
      <header>
        <h1>My To-Do List</h1>
      </header>
      <form>
        Title <input />
        Content <input />
        <button>Add</button>
      </form>
      <section>
        <h2>{title}</h2>
        <p>{text}</p>
        <button>Delete</button>
        &nbsp;
        <button>{isDone ? "Cancle" : "Done"}</button>
      </section>
    </div>
  );
}

export default App;

▶️ 이후 코드 작성이 용이하도록 다음과 같이 컴포넌트르 분리한다. (컴포넌트 분리는 다음 포스팅 참고.)

App 컴포넌트 > Header / TodoController > TodoForm / TodoList > TodoCards


3. Input 창에 입력한 값 연결하기

input 태그를 useState를 사용하여, rendering을 진행한다.
= input 창에 입력되는 값이 setValue를 통해 새롭게 저장된다.

  const [title, setTitle] = useState("");
  const [text, setText] = useState("");

  const addTitleHandler = (event) => {
    setTitle(event.target.value);
  };

  const addTextHandler = (event) => {
    setText(event.target.value);
  };

TodoForm 컴포넌트의 input 태그에서 value={}onChange={}를 달아서 input 창을 연결해준다.

Title <input className="titleClass" value={title} onChange={addTitleHandler} /> 
Content <input className="textClass" value={text} onChange={addTextHandler} />

4. Todo Card 추가하기

input 창에 입력한 값을 받아서, Add 버튼을 누르면 카드가 생성되도록 해보자.

  • form 태그에 함수를 연결해줘야 하기 때문에, keyboard 키를 눌렀을 때, 자동으로 새로고침이 되는 것을 막아준다. = preventDefault()
  • newCards 라는 새로운 카드 객체를 생성한다.
  • 이후 setCards로 기존의 cards의 배열을 풀고, 해당 배열에 newCards라는 객체를 추가하여, re-rendering을 하여 새롭게 화면의 카드를 추가한다.
/* card 추가하기 */
  const addSubmit = (e) => {
    e.preventDefault();

    // 빈 input 추가 막기
    if (!title || !text) {
      return;
    }

    const newCards = {
      id: cards.length + 1,
      title,
      text,
      isDone: false, // 초기 생성된 카드의 isDone은 false로 지정한다. 
    };
    setCards([...cards, newCards]);

    // 카드 추가 후, input 창 초기화 하기
    setTitle("");
    setText("");

    e.target.reset();
  };

TodoForm 컴포넌트에서 form 태그에 addSubmit 함수를 onSubmit에 연결해준다.

  • form 태그 내부의 Add 버튼의 typesubmit으로 설정한다.
<form className="inputStyle" onSubmit={addSubmit}>
    <button id="addBtn" type="submit" className="btn btn-outline-dark"> Add </button>
</form>

TodoList 컴포넌트를 통해, TodoCards를 map 메소드를 이용하여 새로운 배열로 그린다.

<ul className="card-container">
    {cards.map(function (item) {
      return (
        <TodoCards />
      );
    })}
</ul>

5. Todo Card 삭제하기

filter 메소드를 이용하여 버튼을 누른 id가 아닌 나머지 카드의 객체만 남긴다. = 해당 id 값을 가진 카드만 삭제된다.

  • Delete의 버튼을 누르면 onClick event가 발생하는데, 해당 카드의 id와 일치하지 않는 card만 filter하여 화면에 남긴다.
//card 삭제하기 버튼
  const removeCardBtn = (id) => {
    const removeCards = cards.filter((card) => card.id !== id);
    setCards(removeCards);
  };

TodoCards에서 Delete 버튼에서 onClick event를 통해 해당 함수가 실행된다.

<button type="button" onClick={() => removeCardBtn(id)}> Delete </button>