React实战:创建待办事项应用 | 前端项目实操

104 阅读3分钟

基本内容来自MDN文档:开始我们的 React 待办清单 - 学习 Web 开发 | MDN

项目预览

使用Vercel部署:TodoMatic

基本功能:

  • 添加任务

  • 标记任务为已完成

  • 删除任务

  • 编辑任务

  • 查看特定任务子集:所有任务、未完成任务,已完成任务

在此基础上添加了两个功能:

  • 数据本地存储(使用 localStorage

  • 设置任务优先级

image.png

组件拆解:

Form.js

用户输入新任务并提交,负责收集用户输入并将其传递到父组件。

image.png

状态管理:用 name 保存输入框内容

事件处理

  • 输入时:动态更新 name

  • 提交时:检查任务是否为空,将任务传递给父组件,并清空输入框。

渲染:一个输入框和提交按钮。

提交任务后清空输入框,防止重复输入。


Todo.js

展示任务信息,进行编辑、删除、完成标记。

状态管理

  • isEditing -> 管理是否处于编辑模式
  • newNamenewPriority:编辑时保存用户输入。

非编辑模式:

  • 显示任务名称、完成状态和优先级
  • 提供编辑和删除按钮

编辑模式:

  • 输入框:修改任务名称
  • 下拉菜单:修改任务优先级
  • 提交按钮:保存编辑结果
  • 取消按钮:退出编辑模式

非编辑页面

image.png

编辑页面

image.png

FilterButton.js

控制任务筛选条件(全部/未完成/已完成)

状态管理

isPressed:表示按钮是否选中,用于高亮当前过滤器。

事件处理

点击时:通过 props.setFilter 将过滤器名称传递给父组件。

渲染

按钮文本显示过滤器名称

image.png

总结来说就是:创建任务、编辑任务、筛选任务

主控组件App.js

核心逻辑

任务状态管理

  • tasks:任务列表,初始化时尝试从 localStorage 加载;新增、删除、编辑任务时更新并存储到 localStorage
  • filter:当前筛选器状态,用于控制任务显示范围(如“全部”、“已完成”、“未完成”)。

任务操作函数

  • addTask:添加任务,分配唯一 id,设置默认优先级 Medium,并更新任务列表。
  • toggleTaskCompleted:切换任务的完成状态。
  • deleteTask:删除指定任务。
  • editTask:编辑任务名称和优先级。
  • updatePriority:单独更新任务的优先级。

筛选器逻辑

  • FILTER_MAP:定义筛选规则(全部、未完成、已完成)。
  • FILTER_NAMES:提取筛选器名称,用于生成筛选按钮列表。

本地存储

  • saveTasksToLocalStorage:在每次状态更新后,将任务列表存储到 localStorage,实现数据持久化。

子组件整合

Form组件

<Form addTask={addTask} />

Todo组件

通过 props 传递任务数据及父组件方法:

<Todo
  id={task.id}
  name={task.name}
  completed={task.completed}
  priority={task.priority}
  toggleTaskCompleted={toggleTaskCompleted}
  deleteTask={deleteTask}
  editTask={editTask}
/>

FilterButton组件

每个按钮通过 setFilter 更新当前筛选器。

const filterList = FILTER_NAMES.map((name) => (
  <FilterButton
    key={name}
    name={name}
    isPressed={name === filter}
    setFilter={setFilter}
  />
));

渲染结构

标题部分

显示任务总数,动态生成任务剩余数量文本:

const tasksNoun = taskList.length !== 1 ? "tasks" : "task";
const headingText = `${taskList.length} ${tasksNoun} remaining`;
<h2 id="list-heading">{headingText}</h2>

筛选按钮组

渲染所有筛选器按钮:

<div className="filters btn-group stack-exception">
  {filterList}
</div>

任务列表

筛选后渲染符合条件的任务:

<ul className="todo-list stack-large stack-exception">
  {taskList}
</ul>

总结

image.png

TodoMatic_App_Flow.png