Todo 앱

발행: (2026년 1월 15일 오후 09:08 GMT+9)
4 min read
원문: Dev.to

Source: Dev.to

소개

첫 번째 로직‑중심 프로젝트(카운터)를 마친 뒤, 복잡성 측면에서 다음 자연스러운 단계로 나아가고 싶었습니다 — UI를 개선하는 것이 아니라 사고 방식을 도전하고 싶었습니다.

그 결과 프로젝트 2: Todo App (Logic‑First, Not UI) 를 시작하게 되었습니다.

왜 Todo App인가?

카운터는 단일 값 상태 로직을 이해하는 데 도움이 되었습니다. Todo 앱은 다음과 같은 사고를 요구합니다:

  • 단일 값이 아닌 배열
  • CRUD 작업(추가, 업데이트, 삭제)
  • 조건부 렌더링
  • 엣지 케이스와 상태 일관성

많은 React 학습자들이 여기서 어려움을 겪는데, 바로 이 지점이 성장하기에 완벽한 장소가 됩니다.

이 프로젝트의 목표는 화려한 인터페이스를 만드는 것이 아니라 문제 해결 접근 방식을 강화하고, 예측 가능한 상태 업데이트를 작성하며, 거의 모든 프론트엔드 애플리케이션에 나타나는 실제 로직 시나리오를 다루는 것이었습니다.

이 글에서는 Todo 앱을 단계별로 어떻게 접근했는지, 로직 선택, 겪은 실수, 그리고 그것을 해결하면서 배운 점을 상세히 설명하겠습니다.

단계별 개발 🚀

레벨 1: 검증이 포함된 Todo 생성 추가

커밋: Level 1: Add todo creation with validation

import { useState } from "react";

function TodoApp() {
  const [todos, setTodos] = useState([]);
  const [task, setTask] = useState("");

  const handleSubmit = () => {
    // Basic validation – prevent empty or whitespace‑only tasks
    if (task.trim() === "") {
      alert("Enter task to add");
      return;
    }

    // Immutable update – create a new array with the new task
    setTodos([...todos, task]);

    // Reset input for better UX
    setTask("");
  };

  return (
    
       setTask(e.target.value)}
        className="border rounded px-2 py-2 w-80 m-2"
      />
      
        Add Task
      

      {/* Render the list of todos */}
      {todos.map((todo, idx) => (
        {todo}
      ))}
    
  );
}

학습 내용

  • 제어된 입력useState를 사용해 폼 입력을 관리하고, 입력 값을 React 상태가 완전히 제어하도록 했습니다.
  • 기본 검증 – 빈 문자열이나 공백만 있는 Todo가 추가되지 않도록 방지해 데이터의 정합성을 유지했습니다.
  • 불변 상태 업데이트(배열) – 기존 배열을 변형하지 않고 스프레드 연산자([…todos, task])를 사용해 새 배열을 생성함으로써 React의 불변성 규칙을 지키고 올바른 재렌더링을 보장했습니다.
  • UX 향상을 위한 입력 초기화 – Todo를 추가한 뒤 setTask("")로 입력 필드를 비워 사용성을 높였습니다.
  • 동적 리스트 렌더링map()을 활용해 Todo 목록을 동적으로 렌더링했습니다.
Back to Blog

관련 글

더 보기 »

개발자? 아니면 그냥 Toolor?

번역할 텍스트를 제공해 주시겠어요? 현재는 이미지 링크만 있어 내용을 확인할 수 없습니다. 텍스트를 복사해서 알려주시면 한국어로 번역해 드리겠습니다.