icon안동민 개발노트

간단한 할 일 목록 앱 만들기


 이 실습에서는 지금까지 학습한 React 개념들을 종합하여 간단한 할 일 목록(Todo List) 애플리케이션을 만들어 보겠습니다.

 이 과정을 통해 컴포넌트 구조 설계, state 관리, props를 통한 데이터 전달, 조건부 렌더링, 리스트 렌더링, 그리고 이벤트 처리 등의 개념을 실제로 적용해 볼 수 있습니다.

1단계 : 프로젝트 설정

 먼저 새로운 React 프로젝트를 생성합니다.

npx create-react-app todo-list-app
cd todo-list-app
npm start

2단계 : 컴포넌트 구조 설계

 우리의 Todo List 앱은 다음과 같은 컴포넌트 구조를 가집니다.

  1. App : 최상위 컴포넌트
  2. TodoList : 할 일 목록을 관리하고 표시하는 컴포넌트
  3. TodoItem : 개별 할 일 항목을 표시하는 컴포넌트
  4. AddTodoForm : 새로운 할 일을 추가하는 폼 컴포넌트

3단계 : 컴포넌트 구현

App.js
import React, { useState } from 'react';
import TodoList from './TodoList';
import AddTodoForm from './AddTodoForm';
 
function App() {
  const [todos, setTodos] = useState([
    { id: 1, text: 'Learn React', completed: false },
    { id: 2, text: 'Build a Todo App', completed: false },
  ]);
 
  const addTodo = (text) => {
    const newTodo = { id: Date.now(), text, completed: false };
    setTodos([...todos, newTodo]);
  };
 
  const toggleTodo = (id) => {
    setTodos(todos.map(todo => 
      todo.id === id ? { ...todo, completed: !todo.completed } : todo
    ));
  };
 
  const deleteTodo = (id) => {
    setTodos(todos.filter(todo => todo.id !== id));
  };
 
  return (
    <div className="App">
      <h1>Todo List</h1>
      <AddTodoForm addTodo={addTodo} />
      <TodoList todos={todos} toggleTodo={toggleTodo} deleteTodo={deleteTodo} />
    </div>
  );
}
 
export default App;

 App 컴포넌트는

  • useState 훅을 사용하여 할 일 목록 상태를 관리합니다.
  • 할 일 추가, 토글, 삭제 함수를 정의하고 이를 하위 컴포넌트에 props로 전달합니다.
TodoList.js
import React from 'react';
import TodoItem from './TodoItem';
 
function TodoList({ todos, toggleTodo, deleteTodo }) {
  return (
    <ul>
      {todos.map(todo => (
        <TodoItem
          key={todo.id}
          todo={todo}
          toggleTodo={toggleTodo}
          deleteTodo={deleteTodo}
        />
      ))}
    </ul>
  );
}
 
export default TodoList;

 TodoList 컴포넌트는

  • todos 배열을 props로 받아 각 할 일에 대해 TodoItem 컴포넌트를 렌더링합니다.
  • map 함수를 사용하여 리스트를 렌더링하며, 각 항목에 고유한 key를 제공합니다.
TodoItem.js
import React from 'react';
 
function TodoItem({ todo, toggleTodo, deleteTodo }) {
  return (
    <li>
      <input
        type="checkbox"
        checked={todo.completed}
        onChange={() => toggleTodo(todo.id)}
      />
      <span style={{ textDecoration: todo.completed ? 'line-through' : 'none' }}>
        {todo.text}
      </span>
      <button onClick={() => deleteTodo(todo.id)}>Delete</button>
    </li>
  );
}
 
export default TodoItem;

 TodoItem 컴포넌트는

  • 개별 할 일 항목을 표시합니다.
  • 체크박스를 통해 완료 상태를 토글할 수 있습니다.
  • 조건부 스타일링을 사용하여 완료된 항목에 취소선을 표시합니다.
  • 삭제 버튼을 통해 항목을 제거할 수 있습니다.
AddTodoForm.js
import React, { useState } from 'react';
 
function AddTodoForm({ addTodo }) {
  const [text, setText] = useState('');
 
  const handleSubmit = (e) => {
    e.preventDefault();
    if (!text.trim()) return;
    addTodo(text);
    setText('');
  };
 
  return (
    <form onSubmit={handleSubmit}>
      <input
        type="text"
        value={text}
        onChange={(e) => setText(e.target.value)}
        placeholder="Add a new todo"
      />
      <button type="submit">Add</button>
    </form>
  );
}
 
export default AddTodoForm;

 AddTodoForm 컴포넌트는

  • 로컬 state를 사용하여 입력 필드의 값을 관리합니다.
  • 폼 제출 시 새로운 할 일을 추가하고 입력 필드를 초기화합니다.

4단계 : 상태 관리 및 Props 전달

  • App 컴포넌트에서 todos 상태와 관련 함수들을 관리합니다.
  • 이 상태와 함수들을 props를 통해 하위 컴포넌트로 전달합니다.
  • useState 훅을 사용하여 컴포넌트의 상태를 관리합니다.

5단계 : 조건부 렌더링

 TodoItem 컴포넌트에서 조건부 렌더링을 사용하여 완료된 항목에 취소선을 적용합니다.

<span style={{ textDecoration: todo.completed ? 'line-through' : 'none' }}>
  {todo.text}
</span>

6단계 : 리스트 렌더링

 TodoList 컴포넌트에서 map 함수를 사용하여 할 일 목록을 렌더링합니다.

{todos.map(todo => (
  <TodoItem
    key={todo.id}
    todo={todo}
    toggleTodo={toggleTodo}
    deleteTodo={deleteTodo}
  />
))}

7단계 : 이벤트 처리

  • TodoItem에서 체크박스 변경과 삭제 버튼 클릭 이벤트를 처리합니다.
  • AddTodoForm에서 폼 제출 이벤트를 처리합니다.

8단계 : 스타일링 (선택사항)

 간단한 CSS를 추가하여 앱의 외관을 개선할 수 있습니다.

 App.css 파일에 다음과 같은 스타일을 추가할 수 있습니다.

.App {
  max-width: 500px;
  margin: 0 auto;
  padding: 20px;
}
 
ul {
  list-style-type: none;
  padding: 0;
}
 
li {
  display: flex;
  align-items: center;
  padding: 10px 0;
  border-bottom: 1px solid #eee;
}
 
input[type="text"] {
  flex-grow: 1;
  padding: 5px;
  margin-right: 10px;
}
 
button {
  padding: 5px 10px;
  background-color: #007bff;
  color: white;
  border: none;
  cursor: pointer;
}
 
button:hover {
  background-color: #0056b3;
}

최종 결과

 이렇게 구현된 Todo List 앱은 다음과 같은 기능을 갖습니다.

  1. 할 일 목록 표시
  2. 새로운 할 일 추가
  3. 할 일 완료/미완료 토글
  4. 할 일 삭제

 이 실습을 통해 우리는 다음과 같은 React 개념들을 실제로 적용해 보았습니다.

  • 컴포넌트 구조 설계 및 구현
  • useState 훅을 사용한 상태 관리
  • props를 통한 데이터 및 함수 전달
  • 조건부 렌더링 (완료된 항목 스타일링)
  • 리스트 렌더링 (map 함수 사용)
  • 이벤트 처리 (폼 제출, 체크박스 변경, 버튼 클릭)
  • 간단한 폼 처리

 이 Todo List 앱은 기본적인 기능만을 구현했지만, 여기에 더 많은 기능을 추가할 수 있습니다.

 예를 들어, 로컬 스토리지를 사용하여 할 일 목록을 저장하거나, 할 일 항목 편집 기능, 완료된 항목 필터링 등의 기능을 추가할 수 있습니다.

 이러한 추가 기능을 구현하면서 useEffect 훅의 사용, 더 복잡한 상태 관리, 컴포넌트 분리 등의 고급 React 개념들을 학습할 수 있습니다.

 이 기본적인 Todo List 앱은 React의 핵심 개념을 실습해보고, 더 복잡한 애플리케이션을 개발하기 위한 좋은 출발점이 될 것입니다.