在日常生活或工作中,待办事项列表(To-Do List)是一项非常实用的工具,帮助我们记录和管理任务,提高效率。
以下,我们将使用React来实现一个基本的待办事项列表,包含以下功能:
- 添加待办事项
- 编辑代办事项
- 删除待办事项
在此过程中,包含搭建开发环境,编写代码,并最终完成这个应用。
程序安装和环境准备
1. 安装Node.js和npm
React项目需要基于Node.js和npm环境
- 前往Node.js官网下载并安装最新的LTS版本(更稳定)或当前版本(最新功能)
- 安装完成后,通过命令行输入以下命令确认版本是否正确:
node -v
npm -v
- 你将看到类似以下输出(版本号因版本不同而异):
v18.16.1
9.5.1
2. 创建React项目
通过create-react-app脚手架快速创建一个React项目:
- 打开终端,执行以下命令创建项目:
npx create-react-app todo-list
cd todo-list
这将自动下载并配置一个完整的React开发环境,包括webpack、Babel等工具。 2. 进入项目目录:
cd todo-list
- 启动开发服务器: 启动后会在浏览器中自动打开项目首页:
npm start
默认访问地址为 http://lacalhost:3000 ,浏览器将自动打开,显示默认的React页面(欢迎页面),说明项目创建成功。
编写待办事项应用
项目目录构建 确保项目的主要目录节后如下:
todo-list/
├── public/
├── src/
│ ├── components/
│ │ ├── TodoList.js
│ │ ├── TodoItem.js
│ ├── App.js
│ ├── index.js
第一步:搭建主组件结构
在项目的src文件夹中修改App.js文件,添加待办事项列表的核心逻辑。
src/App.js
import React, { useState } from "react";
const App = () => {
// 用于存储所有待办事项的状态,每个事项包含 id、text 和 isEditing 属性
const [todos, setTodos] = useState([]);
// 用于管理输入框中的当前值的状态
const [inputValue, setInputValue] = useState("");
// 添加待办事项
const addTodo = () => {
if (inputValue.trim()) {
// 将新事项添加到 todos 中,并清空输入框
setTodos([...todos, { id: Date.now(), text: inputValue.trim(), isEditing: false }]);
setInputValue("");
}
};
// 删除待办事项
const deleteTodo = (id) => {
// 通过过滤删除指定 id 的事项
setTodos(todos.filter((todo) => todo.id !== id));
};
// 开始编辑某个待办事项
const startEditing = (id) => {
setTodos(
todos.map((todo) =>
todo.id === id ? { ...todo, isEditing: true } : todo // 将目标事项的 isEditing 设置为 true
)
);
};
// 更新待办事项的内容
const updateTodo = (id, newText) => {
setTodos(
todos.map((todo) =>
todo.id === id ? { ...todo, text: newText, isEditing: false } : todo // 更新内容并结束编辑状态
)
);
};
return (
<div style={{ padding: "20px", maxWidth: "400px", margin: "auto" }}>
<h1>待办事项列表</h1>
{/* 输入框和添加按钮 */}
<div style={{ display: "flex", marginBottom: "10px" }}>
<input
type="text"
value={inputValue}
onChange={(e) => setInputValue(e.target.value)} // 同步输入框的值到状态
placeholder="输入待办事项"
style={{ flex: 1, marginRight: "10px" }}
/>
<button onClick={addTodo}>添加</button>
</div>
{/* 待办事项列表 */}
<ul style={{ padding: 0, listStyleType: "none" }}>
{todos.map((todo) => (
<li
key={todo.id}
style={{
display: "flex",
justifyContent: "space-between",
marginBottom: "10px",
borderBottom: "1px solid #ccc",
paddingBottom: "5px",
}}
>
{/* 如果是编辑状态,显示输入框和保存按钮 */}
{todo.isEditing ? (
<>
<input
type="text"
defaultValue={todo.text} // 设置默认值为当前待办事项内容
onBlur={(e) => updateTodo(todo.id, e.target.value)} // 失去焦点时更新内容
/>
<button onClick={() => updateTodo(todo.id, todo.text)}>保存</button>
</>
) : (
<>
<span>{todo.text}</span> {/* 显示待办事项内容 */}
<button onClick={() => startEditing(todo.id)}>编辑</button>
</>
)}
{/* 删除按钮 */}
<button onClick={() => deleteTodo(todo.id)}>删除</button>
</li>
))}
</ul>
</div>
);
};
export default App;
第二步:分离单个待办项逻辑(可选)
为了让代码更具可读性,将每个待办事项的逻辑提取到一个独立的组件中:
- 创建
src/TodoItem.js文件
import React, { useState } from "react";
// 单个待办事项组件
const TodoItem = ({ todo, deleteTodo, startEditing, updateTodo }) => {
// 局部状态:用于管理编辑状态下输入框的值
const [editValue, setEditValue] = useState(todo.text);
// 更新待办事项的处理函数
const handleUpdate = () => {
if (editValue.trim()) {
// 如果输入值非空,则调用父组件传递的 updateTodo 方法
updateTodo(todo.id, editValue.trim());
}
};
return (
<li
style={{
display: "flex", // 使用 flex 布局使内容分布合理
justifyContent: "space-between", // 两端对齐,左边是内容,右边是操作按钮
marginBottom: "10px", // 列表项之间的间距
borderBottom: "1px solid #ccc", // 分隔线
paddingBottom: "5px", // 列表项内边距
}}
>
{/* 判断当前待办事项是否处于编辑状态 */}
{todo.isEditing ? (
<>
{/* 编辑状态时显示输入框和保存按钮 */}
<input
type="text"
value={editValue} // 输入框的值绑定到 editValue
onChange={(e) => setEditValue(e.target.value)} // 更新输入框的值
/>
<button onClick={handleUpdate}>保存</button> {/* 点击保存后更新事项内容 */}
</>
) : (
<>
{/* 非编辑状态时显示事项文本和编辑按钮 */}
<span>{todo.text}</span> {/* 显示待办事项的文本 */}
<button onClick={() => startEditing(todo.id)}>编辑</button> {/* 启用编辑模式 */}
</>
)}
{/* 删除按钮 */}
<button onClick={() => deleteTodo(todo.id)}>删除</button> {/* 调用删除函数 */}
</li>
);
};
export default TodoItem;
- 在
App.js中引入TodoItem:
import TodoItem from "./TodoItem";
项目运行详细说明
启动项目
- 运行命令:在终端输入以下命令,启动开发服务器:
npm start
-
启动过程:
- 开发服务器启动:
npm start启动 React 自带的开发服务器(基于 webpack-dev-server)。 - 浏览器自动打开:服务器启动后,默认会在浏览器中打开项目主页(通常是
http://localhost:3000) - 实时热加载:任何代码更改都会自动更新页面,无需手动刷新。
- 开发服务器启动:
-
启动成功后:您会看到一个基本的待办事项应用界面,包括输入框、添加按钮和空列表。
应用交互功能详解
- 添加任务
- 操作步骤:
- 在输入框中输入任务内容,例如“买菜”。
- 点击输入框右侧的“添加”按钮。
- 功能实现:
- 输入的内容会通过状态
inputValue管理。 - 点击“添加“时,触发
addTodo方法,将输入框的内容作为新任务添加到todos列表中。 - 输入框清空,等待下一次输入。
- 输入的内容会通过状态
- 结果:新任务将显示在列表中。
- 操作步骤:
示例:
- 输入“写作业”,点击“添加”,列表中显示:
写作业[编辑][删除]
- 编辑任务
- 操作步骤:
-
- 点击任务右侧的“编辑”按钮。
- 任务内容变为可编辑状态,输入框显示当前内容。
- 修改内容后,点击“保存”按钮。
-
- 功能实现:
- 点击“编辑”按钮时,触发
startEditing方法,将任务的isEditing设置为true。 - 输入框中可以修改当前任务内容。
- 点击“保存”按钮时,触发
updateTodo方法,将新的内容保存到任务中,同时退出编辑状态。
- 点击“编辑”按钮时,触发
- 结果:任务内容更新为修改后的内容。
- 操作步骤:
示例:
- 原任务:”写作业“。点击”编辑“,修改为”写数学作业“,点击”保存“,列表更新为:
写数学作业 [编辑] [删除]
- 删除任务
- 操作步骤:
- 点击任务右侧的“删除”按钮。
- 功能实现:
- 点击“删除”时,触发
deleteTodo方法,根据任务的id从todos列表中移除该任务。 - 列表重新渲染,移除后的任务不再显示。
- 点击“删除”时,触发
- 结果:任务被删除,列表中不再显示该任务。
- 操作步骤:
示例:
- 原任务列表:
写作业[编辑][删除]
买菜[编辑][删除]
- 点击“买菜”右侧的”删除”,更新后列表显示:
写作业 [编辑][删除]
页面整体功能运行流程
-
启动开发服务器,加载页面。
-
使用输入框添加待办事项,每次添加都动态更新列表。
-
使用编辑功能修改现有任务内容,保存后反映更新。
4.使用删除功能移除不再需要的任务,列表保持同步更新。
通过以上功能,用户可以高效管理自己的任务列表,充分利用该应用的增删改功能来优化日常任务安排。
总结和感想
总结
- 这个待办事项应用通过 React 的组件化开发,实现了 添加、编辑、删除 三大核心功能。
- 代码中运用了 React 的 状态管理 和 事件处理,展示了如何在小型项目中灵活应用这些技术。
- 通过分离组件(如
TodoItem),代码结构清晰、可维护性高,便于功能扩展。
感想
- React 的实时热加载和组件化开发让构建用户界面变得直观且高效。
- 虽然是一个简单的待办事项应用,但每个功能的实现过程能帮助更好地理解 React 的核心概念,如 状态提升 和 单向数据流。
- 这个项目既适合作为 React 初学者的练习项目,也能为更复杂的应用打下基础。
总的来说,通过开发这个应用,不仅强化了 React 的基本知识,还培养了将功能模块化的思维方式,这对日后开发大型项目十分有帮助。此外,这个项目虽然功能简单,但开发过程中也会遇到一些小挑战,比如 如何高效管理组件的状态 和 在编辑功能中保证用户体验流畅。通过解决这些问题,可以更深入地理解 React 的核心机制。
整体来说,这样的小项目非常适合练手:既能迅速上手 React,也能从中体会到编程带来的成就感,同时为未来构建更复杂的应用打下坚实的基础。