# Todo List 应用（入门）

URL: https://caijiao.org/react/chapter13/todo-list
Source: docs/react/chapter13/todo-list.md
Description: Todo List 应用是学习 React 基础的经典项目，通过该应用可以掌握 React 的组件化开发、状态管理、事件处理等基础知识。

Todo List 是开发者在学习任何前端框架时都会接触到的经典项目。通过实现一个简单的待办事项（Todo）应用，开发者可以深入理解 React 的基本概念，包括组件化开发、状态管理、事件处理等。

## 1. 创建 Todo List 项目

首先，通过 `create-react-app` 创建一个新的 React 项目：

```bash
npx create-react-app todo-list
cd todo-list
npm start
````

这会启动一个默认的 React 项目，接下来我们可以根据需求进行修改。

## 2. 项目结构

一个简单的 Todo List 应用需要以下几个组件：

* **App**：主应用组件，负责渲染 Todo 列表以及添加新任务。
* **TodoItem**：单个 Todo 项组件，负责显示每个任务和删除任务的功能。
* **TodoForm**：表单组件，用于输入新任务。

### 目录结构

```bash
src/
  ├── components/
  │   ├── TodoForm.js
  │   └── TodoItem.js
  ├── App.js
  └── index.js
```

## 3. 实现 TodoList 功能

### 3.1 TodoItem 组件

在 `TodoItem.js` 文件中，我们创建一个简单的组件，接收任务内容和删除功能作为 props。

```js
import React from 'react';

function TodoItem({ todo, onDelete }) {
  return (
    <div>
      <span>{todo}</span>
      <button onClick={onDelete}>删除</button>
    </div>
  );
}

export default TodoItem;
```

### 3.2 TodoForm 组件

在 `TodoForm.js` 文件中，我们创建一个表单，用于输入新任务。

```js
import React, { useState } from 'react';

function TodoForm({ onAddTodo }) {
  const [todo, setTodo] = useState('');

  const handleSubmit = (e) => {
    e.preventDefault();
    if (todo) {
      onAddTodo(todo);
      setTodo('');
    }
  };

  return (
    <form onSubmit={handleSubmit}>
      <input 
        type="text" 
        value={todo} 
        onChange={(e) => setTodo(e.target.value)} 
        placeholder="输入任务"
      />
      <button type="submit">添加</button>
    </form>
  );
}

export default TodoForm;
```

### 3.3 App 组件

在 `App.js` 文件中，我们将两个组件结合起来，管理 Todo 列表的状态，并传递必要的 props。

```js
import React, { useState } from 'react';
import TodoForm from './components/TodoForm';
import TodoItem from './components/TodoItem';

function App() {
  const [todos, setTodos] = useState([]);

  const addTodo = (todo) => {
    setTodos([...todos, todo]);
  };

  const deleteTodo = (index) => {
    setTodos(todos.filter((_, i) => i !== index));
  };

  return (
    <div>
      <h1>Todo List</h1>
      
      <div>
        {todos.map((todo, index) => (
          <TodoItem 
            key={index} 
            todo={todo} 
            onDelete={() => deleteTodo(index)} 
          />
        ))}
      </div>
    </div>
  );
}

export default App;
```

## 4. 完善应用功能

### 4.1 添加任务

每次提交表单时，`TodoForm` 会调用 `onAddTodo` 函数，将输入的任务内容添加到 `todos` 数组中。

### 4.2 删除任务

每个 `TodoItem` 都有一个删除按钮，点击时会调用 `onDelete` 函数，移除对应的任务。

## 5. 总结

通过这个简单的 Todo List 应用，开发者可以了解 React 组件的组织方式、如何管理组件状态以及如何处理事件。尽管这个项目简单，但它是学习 React 的一个重要入门实践，可以帮助开发者更好地掌握 React 的核心概念。
