React+TypeScript实现一个简单的待办事项表

130 阅读3分钟

效果展示

屏幕截图 2024-11-25 230556.png

核心技术点

  1. React 状态管理

    • 使用 useState 来存储任务列表(todos)和筛选条件(filter)。
    • 每个操作(添加、删除、编辑、切换状态)都通过更新状态完成。
    • 使用不可变操作(mapfilter 等)生成新的状态,确保 React 正确触发重新渲染。
  2. 事件处理

    • 使用 React 的事件处理器(如 onClickonChange)。
    • 通过回调函数将子组件的用户操作传递到父组件中,保持状态管理集中。
  3. 数组操作

    • map:用于修改数组中的特定任务(如编辑和切换完成状态)。
    • filter:用于筛选任务(如删除任务或筛选未完成任务)。
    • spread 运算符 (...) :用于创建新的数组(如添加任务时)。
  4. 状态更新的最佳实践

    • 确保状态是不可变的,通过创建新的数组或对象来更新状态,而不是直接修改原始数据。
    • 避免直接修改数组或对象中的属性,确保 React 能正确检测状态变化。

重要的功能函数

const addTodo = (text: string) => {
    const newTodo: Todo = {id: Date.now(), text: text, completed: false};
    setTodos([...todos, newTodo]);
}
/*实现逻辑:
创建一个新的待办事项 newTodo:
id: 使用当前时间戳(Date.now())生成唯一 ID。
text: 传入的参数 text,表示待办事项的内容。
completed: 初始值为 false,表示任务未完成。
使用 setTodos 更新状态,将 newTodo 添加到当前的 todos 列表中:
setTodos([...todos, newTodo]) 创建了一个新的数组,包括现有的 todos 和新任务。*/


const toggleTodo = (id: number) => {
    const newTodos = todos.map(todo => {
        if (todo.id === id) {
            todo.completed = !todo.completed;
        }
        return todo;
    });
    setTodos(newTodos);
}
/*实现逻辑:
遍历当前的 todos 列表(使用 map 方法)。
对于每个任务(todo),检查 id 是否匹配传入的 id:
如果匹配,则通过 todo.completed = !todo.completed 切换任务的完成状态。
否则保持不变。
更新 todos 状态为修改后的列表(newTodos)。*/


const deleteTodo = (id: number) => {
    const newTodos = todos.filter(todo => todo.id !== id);
    setTodos(newTodos);
}
/*实现逻辑:
使用 filter 方法生成新的任务列表(newTodos),只保留 id 不等于传入参数 id 的任务。
调用 setTodos 更新状态为删除后的任务列表。*/


const editTodo = (id: number, newText: string) => {
    const newTodos = todos.map(todo => {
        if (todo.id === id) {
            todo.text = newText;
        }
        return todo;
    });
    setTodos(newTodos);
}
/*实现逻辑:
遍历当前任务列表(todos)。
对于每个任务(todo),检查 id 是否匹配传入参数 id:
如果匹配,则更新其 text 为新内容(newText)。
否则保持不变。
调用 setTodos 更新状态为修改后的任务列表。*/


const getFilteredTodos = () => {
    switch (filter) {
        case "all":
            return todos;
        case "active":
            return todos.filter(todo => !todo.completed);
        case "completed":
            return todos.filter(todo => todo.completed);
        default:
            return todos;
    }
}
/*实现逻辑:
根据 filter 值,使用 switch 语句筛选任务:
"all":返回完整的任务列表(todos)。
"active":通过 filter 返回所有 completed 为 false 的任务(未完成的任务)。
"completed":通过 filter 返回所有 completed 为 true 的任务(已完成的任务)。
返回筛选结果。*/

传入props

   <div className="home">
        <h1>TodoList</h1>
        <AddTodo addTodo ={addTodo}/>
        <TodoList todos={getFilteredTodos()} toggleTodo={toggleTodo} deleteTodo={deleteTodo} editTodo = {editTodo}/>
        <TodoFilter setFilter = {setFilter}/>
    </div>

总结

这个 Todo List 项目是 React 中的经典案例,通过操作数组和状态,能够很好地学习以下内容:

  • React 的状态管理与事件处理。
  • 数据不可变性和数组操作方法。
  • React 组件的分离和逻辑复用。

扩展功能和优化点还能进一步提升项目的实用性和用户体验。