使用React 实现一个简单的待办事项列表 | 豆包MarsCode AI刷题

90 阅读4分钟

React 实现简单待办事项列表

待办事项列表是前端开发中常见的练习项目,既可以巩固 React 基础,又能帮助开发者理解状态管理、组件设计以及事件处理等重要概念。在这篇文章中,我们将一步步实现一个带有添加、编辑和删除功能的待办事项列表。


一、需求分析

一个功能完整的待办事项列表至少需要实现以下功能:

  1. 添加任务:允许用户输入任务并将其添加到列表。
  2. 编辑任务:支持修改已添加任务的内容。
  3. 删除任务:用户可以删除不需要的任务。
  4. 交互提示:实时更新列表内容,保持流畅的用户体验。

技术选型:选择 React 实现,利用其组件化和状态管理能力来组织代码。


二、功能分解

在实现时,需要将待办事项列表分解为以下核心模块:

  1. 任务输入框(TaskInput) :负责接受用户输入,并通过事件将任务传递给列表。
  2. 任务列表(TaskList) :负责显示所有任务,包含编辑和删除功能。
  3. 任务项(TaskItem) :独立处理每个任务的显示和交互。
  4. 主容器(App) :负责管理任务的整体状态(任务数组)并分发操作。

通过模块化设计,可以将代码拆分为小而明确的功能块,提高可维护性。


三、核心知识点解析

1. React 状态管理 React 的 useState 钩子是管理组件内状态的核心工具。这里,任务列表的所有状态会集中在 App 中,然后通过 Props 向下传递。

2. 数据流动 React 的单向数据流模式让任务状态的修改显得直观。任何更新操作都通过父组件提供的回调完成,并同步到子组件。

3. 事件处理 事件处理是待办事项列表的关键。通过监听表单输入、按钮点击等事件,我们可以动态地添加、修改和删除任务。


四、代码实现

以下是代码实现的分步解析。

1. 创建任务输入框组件
import React, { useState } from 'react';

function TaskInput({ onAddTask }) {
  const [inputValue, setInputValue] = useState('');

  const handleAdd = () => {
    if (inputValue.trim()) {
      onAddTask(inputValue);
      setInputValue('');
    }
  };

  return (
    <div>
      <input
        type="text"
        value={inputValue}
        onChange={(e) => setInputValue(e.target.value)}
        placeholder="输入待办事项"
      />
      <button onClick={handleAdd}>添加</button>
    </div>
  );
}

export default TaskInput;

TaskInput 组件提供了一个输入框,用户可以输入任务。onAddTask 是一个父组件传递的回调函数,用于将新任务添加到列表中

2. 创建任务项组件
function TaskItem({ task, onEdit, onDelete }) {
  const [isEditing, setIsEditing] = useState(false);
  const [editValue, setEditValue] = useState(task.text);

  const handleEdit = () => {
    onEdit(task.id, editValue);
    setIsEditing(false);
  };

  return (
    <div>
      {isEditing ? (
        <>
          <input
            type="text"
            value={editValue}
            onChange={(e) => setEditValue(e.target.value)}
          />
          <button onClick={handleEdit}>保存</button>
        </>
      ) : (
        <>
          <span>{task.text}</span>
          <button onClick={() => setIsEditing(true)}>编辑</button>
        </>
      )}
      <button onClick={() => onDelete(task.id)}>删除</button>
    </div>
  );
}

export default TaskItem;

TaskItem 负责显示单个任务内容。我们使用 isEditing 状态区分“查看”和“编辑”模式,允许用户修改任务。

3. 创建任务列表组件
function TaskList({ tasks, onEditTask, onDeleteTask }) {
  return (
    <div>
      {tasks.map((task) => (
        <TaskItem
          key={task.id}
          task={task}
          onEdit={onEditTask}
          onDelete={onDeleteTask}
        />
      ))}
    </div>
  );
}

export default TaskList;

TaskList 组件接受任务数组并将其映射为 TaskItem。父组件负责提供编辑和删除任务的逻辑。

4. 集成到主容器
import React, { useState } from 'react';
import TaskInput from './TaskInput';
import TaskList from './TaskList';

function App() {
  const [tasks, setTasks] = useState([]);

  const addTask = (text) => {
    setTasks([...tasks, { id: Date.now(), text }]);
  };

  const editTask = (id, newText) => {
    setTasks(
      tasks.map((task) => (task.id === id ? { ...task, text: newText } : task))
    );
  };

  const deleteTask = (id) => {
    setTasks(tasks.filter((task) => task.id !== id));
  };

  return (
    <div>
      <h1>待办事项列表</h1>
      <TaskInput onAddTask={addTask} />
      <TaskList tasks={tasks} onEditTask={editTask} onDeleteTask={deleteTask} />
    </div>
  );
}

export default App;

App 是整个应用的状态中心。我们将任务数组的增删改操作封装成函数,并通过 Props 传递给子组件。

五、思考

1. 功能扩展性 虽然当前实现满足基础需求,但未来可以扩展为持久化存储(如 LocalStorage)或增加任务完成状态。

2. 数据结构设计 任务的 ID 使用 Date.now() 生成,在复杂应用中可以引入 UUID,以确保唯一性。

3. 用户体验 可以加入动画效果,如任务添加和删除时的过渡动效,提升视觉吸引力。


六、总结

通过分解需求、模块化设计和逐步实现,完成了一个简单但功能完善的待办事项列表。在这个过程中,不仅复习了 React 的基本能力,还思考了如何设计清晰的组件结构,提高代码的可扩展性和可维护性。这种实践模式对任何前端项目开发都有借鉴意义。