글쓰는쿼카의 PM 여정

🐤[베이직] useState 응용예시 - 회원가입, 할일목록(TodoList) 본문

개발/React

🐤[베이직] useState 응용예시 - 회원가입, 할일목록(TodoList)

글쓰는쿼카 joymet33 2024. 5. 29. 22:54

0. 기본정보

#스파르타코딩클럽 #내일배움캠프(프론트엔드_React) #31일/94일
- 학습주제 : [베이직] [리액트 2강] useState 응용 예시와 컴포넌트  

- 학습내용 : useState 응용예시 - 할일목록(TodoList)

- 특별사항 : [특강] 좋은 개발잘의 비밀 by 최원장 튜터

- 학습일 : 2024. 5. 29.


1. 배운 내용 요약

▶ <form> 제출하기 === input값 저장
▶ Todo 삭제하기 버튼 구현하기
▶ Todo 수정하기 버튼 구현하기

 

1) <form> 제출하기 === input값 저장

  const handleSubmit = (e) => {
    e.preventDefault();

    // falsy한 value는 저장하지 않기 : if, trim()
    if (!value.trim()) return;

    // truth한 value는 저장하기 : 2단계
    // 1. 새로운 객체 만들기 : const newTodo
    const newTodo = {
      id: Date.now(),
      text: value,
      isDone: false,
    };

    // 2. 기존 배열에 추가하기 : setTodos(), ...(spread operator)
    setTodos([newTodo, ...todos]);
    setValue("");
  };

 

2) Todo 삭제하기 버튼 구현하기

  // Todo의 삭제 버튼 : filter
  // ==> 원리 설명: 삭제하고자 하는 todo만 setTodos에서 걸러내기
  // ==> 필수 요건: 고유한 id
  const handleDeleteTodo = (id) => {
    setTodos(
      todos.filter((todo) => {
        return todo.id !== id;
      })
    );
  };

 

3) Todo 수정하기 버튼 구현하기

  // Todo의 수정 버튼 : map, 삼항연산자, ...(spread operator)
  // ==> 원리 설명: setTodos에 수정하고자 하는 내용을 수정하여 다시 저장하기
  // ==> 필수 요건: 고유한 id, map함수의 key
  const handleToggleTodo = (id) => {
    setTodos(
      todos.map((todo) =>
        todo.id !== id ? { ...todo, isDone: !todo.isDone } : todo
      )
    );
  };

 

4) 완성 코드

더보기
import { useState } from "react";

function App() {
  const [value, setValue] = useState("");
  const [todos, setTodos] = useState([
    {
      id: Date.now(),
      text: "test todo",
      isDone: false,
    },
  ]);

  const handleSubmit = (e) => {
    e.preventDefault();

    // falsy한 value는 저장하지 않기 : if, trim()
    if (!value.trim()) return;

    // truth한 value는 저장하기 : 2단계
    // 1. 새로운 객체 만들기 : const newTodo
    const newTodo = {
      id: Date.now(),
      text: value,
      isDone: false,
    };

    // 2. 기존 배열에 추가하기 : setTodos(), ...(spread operator)
    setTodos([newTodo, ...todos]);
    setValue("");
  };

  // Todo의 삭제 버튼 : filter
  // ==> 원리 설명: 삭제하고자 하는 todo만 setTodos에서 걸러내기
  // ==> 필수 요건: 고유한 id
  const handleDeleteTodo = (id) => {
    setTodos(
      todos.filter((todo) => {
        return todo.id !== id;
      })
    );
  };

  // Todo의 수정 버튼 : map, 삼항연산자, ...(spread operator)
  // ==> 원리 설명: setTodos에 수정하고자 하는 내용을 수정하여 다시 저장하기
  // ==> 필수 요건: 고유한 id, map함수의 key
  const handleToggleTodo = (id) => {
    setTodos(
      todos.map((todo) =>
        todo.id !== id ? { ...todo, isDone: !todo.isDone } : todo
      )
    );
  };

  return (
    <div>
      <h1>Todo List</h1>
      {/* <form> 기능
      1. <form>태그 onSubmit 바로 입력
      2. <button>태그 type="submit" */}
      <form onSubmit={handleSubmit}>
        <input
          value={value}
          onChange={(e) => setValue(e.target.value)}
          type="text"
          placeholder="Todo를 추가하세요"
        />
        <button type="submit">추가</button>
      </form>
      <ul>
        {/* <li>태그를 map함수로 찍어내기*/}
        {todos.map((todo) => {
          return (
            <li
              key={todo.id}
              style={{
                textDecoration: todo.isDone ? "line-through" : "none",
              }}
            >
              <span>{`${todo.text}`}</span>
              <button onClick={() => handleToggleTodo(todo.id)}>
                {todo.isDone ? "취소" : "완료"}
              </button>
              <button onClick={() => handleDeleteTodo(todo.id)}>삭제</button>
            </li>
          );
        })}
      </ul>
    </div>
  );
}

export default App;

2. 오류일지

1) 문제 -  왜 '완료' 버튼을 누르면 모든 Todo가 한꺼번에 바뀌는 거지?

2) 해결

(추후 보충)

 


3. [특강] 좋은 개발자의 비밀

"시행착오 !== 착오"
지금 격고 있는 실수들은 최고의 선택을 하기 위한 중간단계입니다. (좌절하지 마세요!)

3. 오늘의 회고

- 칭찬 :

  • React 숙련 주차 개인과제를 포기하지 않고 끝까지 최선을 다함👏
  • 팀회의 추가: (기존) 오늘의 다짐(9:00) >> (변경) 오늘의 다짐(9:00) + 오후점검(14:00)

- 반성 :

  • 자투리 시간을 우숩게 본 것 - 티끌모아 태산..!
  • '힘들다'는 이유로 '노력'을 게을리 한 것

- 보충 : [베이직] 컴포넌트, 숙제 오류 해결/ [개인과제] 재제출