使用 React 构建待办事项列表的实现与思考
构建一个简单的待办事项列表是学习 React 的重要实践,它涵盖了组件管理、状态管理以及交互的处理等核心知识点。本次实现的功能包括添加、编辑、删除待办事项。以下是对实现过程的讲解和一些个人思考。
功能实现解析
1. 数据管理
在本例中,useState 用于管理待办事项数据:
const [todos, setTodos] = useState<TodoRecord[]>(fakeTodos.getAll());
通过 fakeTodos 模拟了后端的数据库操作。实际开发中可以用接口替换这个部分。
关键思考:
- 真实开发中,数据的持久化是重要的一环。此处的
fakeTodos只是临时数据存储,实际项目中可以使用 Redux 或 Context 管理复杂数据流。 - 可以引入乐观更新(Optimistic Updates)来优化用户体验,比如假定操作成功后立即更新 UI,再处理实际的服务器响应。
2. 新增待办事项
新增的核心逻辑位于 handleCreate 函数中:
const handleCreate = (e: any) => {
e.preventDefault();
const formData = new FormData(e.currentTarget.form!);
const title = formData.get("title") as string;
fakeTodos.create({ title, status: "pending" });
setTodos(fakeTodos.getAll());
};
此处使用了 FormData 提取表单数据并调用数据接口新增记录。
关键思考:
- 表单验证是新增操作不可忽视的部分,比如检测空标题或标题长度的限制。
- 如果使用实际的后端接口,还需处理接口调用的异常情况。
3. 编辑待办事项
编辑的逻辑分为两步:
- 初始化编辑:通过
handleEdit获取待编辑的待办事项,并展示对话框。 - 提交修改:
handleUpdate用于提交新的待办事项数据。
const handleEdit = (id: string) => {
const todo = fakeTodos.records[id];
if (!todo) return;
setEditTodo(todo);
(document.getElementById("edit-dialog") as HTMLDialogElement)?.showModal();
};
编辑完成后,数据更新并刷新状态:
const handleUpdate = (e: any) => {
e.preventDefault();
const formData = new FormData(e.currentTarget.form!);
const title = formData.get("title") as string;
const status = formData.get("status") as "pending" | "completed";
fakeTodos.update({ id: editTodo?.id, title, status });
setTodos(fakeTodos.getAll());
setEditTodo(null);
};
关键思考:
useState存储了当前编辑的editTodo,在多人协作时,需特别注意状态管理的一致性。- 使用对话框交互虽然直观,但可能不够移动端友好,可以探索更适配移动设备的方案,如底部弹窗(bottom sheet)。
4. 删除待办事项
删除的逻辑相对简单:
const handleDelete = (id: string) => {
fakeTodos.delete(id);
setTodos(fakeTodos.getAll());
};
点击按钮后直接调用 fakeTodos.delete 删除记录,并刷新状态。
关键思考:
- 真实项目中,删除操作最好设计为双确认机制,以避免用户误操作。
- 在复杂系统中,可以通过软删除(soft delete)记录,以便未来恢复。
UI 设计与交互
-
列表展示: 使用
map遍历待办事项,配合样式实现清单展示:{todos.map((todo, index) => ( <div key={todo.id} className="flex justify-between items-center p-2 border border-gray-300 rounded-md gap-3"> <span style={{textDecoration: todo.status === "completed" ? "line-through" : "none"}} className="text-lg"> {index + 1}-{todo.title} </span> <div className="flex gap-2"> <button onClick={() => handleEdit(todo.id)} className="bg-blue-500 text-white px-2 py-1 rounded-md">Edit</button> <button onClick={() => handleDelete(todo.id)} className="bg-red-500 text-white px-2 py-1 rounded-md">Delete</button> </div> </div> ))}通过
textDecoration标注完成的事项,简洁直观。 -
对话框的使用: React 中没有原生的
dialog组件,此处直接使用 HTML 的<dialog>元素,通过showModal和close控制对话框显示。
关键思考:
- 对话框功能很适合简单的表单交互,但在复杂表单或需要更多用户提示的情况下,可以考虑使用更高级的 UI 库,如 Material-UI 的 Dialog 组件。
总结与优化方向
-
状态管理优化
当前实现将todos和editTodo独立管理,如果待办事项量级变大,可以引入 Context 或 Redux,使状态管理更高效。 -
交互优化
- 添加输入验证功能,例如防止空标题。
- 删除前增加确认对话框。
-
扩展功能
- 支持多用户协作,增加用户权限管理。
- 实现任务优先级排序,让用户可自定义任务顺序。
本案例以简单、直观的方式实现了一个待办事项列表,涵盖了 React 的核心概念,同时对实际项目中的潜在优化方向进行了探讨。希望对读者学习和开发实践有所帮助!