效果图
一、创建一个待办事项列表组件(比如 TodoList.js):
import React, { useState } from 'react';
import './TodoList.css'; // 导入自定义的CSS样式
function TodoList() {
const [todos, setTodos] = useState([]);
const [newTodo, setNewTodo] = useState('');
const [editIndex, setEditIndex] = useState(-1);
const addTodo = () => {
if (newTodo.trim() !== '') {
if (editIndex === -1) {
setTodos([...todos, newTodo]);
} else {
const updatedTodos = [...todos];
updatedTodos[editIndex] = newTodo;
setTodos(updatedTodos);
setEditIndex(-1);
}
setNewTodo('');
}
};
const editTodo = (index) => {
setNewTodo(todos[index]);
setEditIndex(index);
};
const deleteTodo = (index) => {
const updatedTodos = todos.filter((_, i) => i !== index);
setTodos(updatedTodos);
};
return (
<div className="todo-list">
<h1>待办事项列表</h1>
<div className="todo-input">
<input
type="text"
placeholder="输入待办事项"
value={newTodo}
onChange={(e) => setNewTodo(e.target.value)}
/>
<button onClick={addTodo}>{editIndex === -1 ? '添加' : '保存'}</button>
</div>
<ul>
{todos.map((todo, index) => (
<li key={index}>
{todo}
<button onClick={() => editTodo(index)}>编辑</button>
<button onClick={() => deleteTodo(index)}>删除</button>
</li>
))}
</ul>
</div>
);
}
export default TodoList;
这里首先是引入了 React 和 useState 这两个从 react 库中导入的模块。同时,通过 import './TodoList.css'; 导入了自定义的CSS样式文件。
function TodoList() {
const [todos, setTodos] = useState([]);
const [newTodo, setNewTodo] = useState('');
const [editIndex, setEditIndex] = useState(-1);
这段代码定义了一个名为 TodoList 的函数组件。在组件内部使用了 useState 钩子来创建了三个状态变量:
todos: 用于存储待办事项的数组。newTodo: 用于存储用户正在输入的新待办事项。editIndex: 用于跟踪正在编辑的待办事项的索引。初始值为 -1,表示没有任何事项正在被编辑。
const addTodo = () => {
if (newTodo.trim() !== '') {
if (editIndex === -1) {
setTodos([...todos, newTodo]);
} else {
const updatedTodos = [...todos];
updatedTodos[editIndex] = newTodo;
setTodos(updatedTodos);
setEditIndex(-1);
}
setNewTodo('');
}
};
这是一个用于添加待办事项的函数。首先,它检查 newTodo 是否包含非空字符。如果是,它会判断当前是添加新事项还是编辑已有事项(通过 editIndex 的值来判断)。如果是添加,就将新事项添加到 todos 数组中。如果是编辑,它会更新已有事项的内容。无论是添加还是编辑,都会将 newTodo 清空,并将 editIndex 重置为 -1。
const editTodo = (index) => {
setNewTodo(todos[index]);
setEditIndex(index);
};
这是一个用于编辑待办事项的函数。当用户点击编辑按钮时,它会将选定的待办事项的内容赋值给 newTodo,同时将 editIndex 设置为选定待办事项的索引,以便稍后知道哪个事项正在被编辑。
const deleteTodo = (index) => {
const updatedTodos = todos.filter((_, i) => i !== index);
setTodos(updatedTodos);
};
这个函数用于删除待办事项。它使用 filter 方法来创建一个新的 todos 数组,其中排除了被选中索引的待办事项。然后,通过 setTodos 更新了 todos 状态。
return (
<div className="todo-list">
<h1>待办事项列表</h1>
<div className="todo-input">
<input
type="text"
placeholder="输入待办事项"
value={newTodo}
onChange={(e) => setNewTodo(e.target.value)}
/>
<button onClick={addTodo}>{editIndex === -1 ? '添加' : '保存'}</button>
</div>
<ul>
{todos.map((todo, index) => (
<li key={index}>
{todo}
<button onClick={() => editTodo(index)}>编辑</button>
<button onClick={() => deleteTodo(index)}>删除</button>
</li>
))}
</ul>
</div>
);
在组件的返回部分,定义了待办事项列表的呈现方式。使用 JSX 来渲染了一个包含输入框、添加/保存按钮、待办事项列表以及编辑和删除按钮的界面。
- 输入框 (
<input>) 显示用户可以输入新待办事项的内容,value属性绑定到newTodo状态,onChange事件用于更新newTodo。 - 添加/保存按钮根据
editIndex的值,显示为 "添加" 或 "保存"。 - 待办事项列表通过
todos.map方法来渲染,每个事项都有一个编辑和删除按钮,它们会调用相应的editTodo和deleteTodo函数。
二、TodoList.css
.todo-list {
text-align: center;
font-family: Arial, sans-serif;
margin: 20px auto;
width: 300px;
border: 1px solid #ddd;
padding: 20px;
border-radius: 5px;
box-shadow: 0px 0px 5px rgba(0, 0, 0, 0.3);
}
.todo-input {
margin-bottom: 10px;
}
.todo-input input {
padding: 5px;
width: 60%;
border-radius: 5px;
border: 1px solid #ddd;
}
.todo-input button {
padding: 5px 10px;
border: none;
background-color: #007bff;
color: #fff;
border-radius: 5px;
cursor: pointer;
}
ul {
list-style: none;
padding: 0;
}
li {
display: flex;
justify-content: space-between;
align-items: center;
border-bottom: 1px solid #ddd;
padding: 5px 0;
}
li button {
padding: 3px 6px;
border: none;
background-color: #dc3545;
color: #fff;
border-radius: 5px;
cursor: pointer;
margin-left: 5px;
}
li button.edit {
background-color: #ffc107;
margin-right: 5px;
}
三、App.js
import React from 'react';
import TodoList from './TodoList';
import './App.css';
function App() {
return (
<div className="app">
<TodoList />
</div>
);
}
export default App;