使用 React 实现待办事项列表的实践记录| 豆包MarsCode AI刷题

79 阅读7分钟

一、项目分析

在使用 React 实现一个简单的待办事项列表时,我们需要考虑几个核心功能:用户能够添加新的待办事项、编辑现有的待办事项以及删除不需要的待办事项。从架构上来看,我们可以将待办事项列表看作是一个数据集合,而 React 通过组件化的方式来处理这些数据的展示和交互。

二、实现步骤

(一)项目搭建

创建 React 项目

首先,使用create - react - app工具创建一个新的 React 项目。在命令行中执行npx create - react - app todo - list(这里假设项目名为 todo - list)。这将生成一个包含基本 React 项目结构的文件夹。

进入项目目录cd todo - list,然后启动项目npm start,此时可以在浏览器中看到默认的 React 应用页面。

(二)组件设计

TodoList 组件

这是整个待办事项列表的核心组件。它将负责渲染所有的待办事项,并处理与待办事项相关的交互操作。

在src文件夹下创建TodoList.js文件。

首先,我们需要导入 React 库:

import React, { useState } from 'react';

这里使用useState钩子来管理组件的状态。

定义组件:

const TodoList = () => {

    // 定义状态,todos用于存储待办事项,newTodo用于存储新添加的待办事项

    const [todos, setTodos] = useState([]);

    const [newTodo, setNewTodo] = useState('');

    return (

        

            

待办事项列表

        

    );

};

export default TodoList;

在上述代码中,todos初始化为一个空数组,用来存储所有的待办事项,newTodo初始化为空字符串,用于获取用户输入的新待办事项。

添加待办事项功能

在TodoList组件中添加一个输入框和一个按钮用于添加待办事项。

const TodoList = () => {

    //...状态定义

    // 处理新待办事项输入的函数

    const handleNewTodoChange = (e) => {

        setNewTodo(e.target.value);

    };

    // 添加待办事项的函数

    const addTodo = () => {

        if (newTodo) {

            setTodos([...todos, { id: Date.now(), text: newTodo, isEditing: false }]);

            setNewTodo('');

        }

    };

    return (

        

            

待办事项列表

            

            添加

        

    );

};

handleNewTodoChange函数用于更新newTodo状态,当用户在输入框中输入内容时,newTodo会随之改变。

addTodo函数在按钮点击时被调用。如果newTodo不为空,它会将新的待办事项添加到todos数组中。新待办事项对象包含id(这里使用当前时间戳作为唯一标识)、text(待办事项内容)和isEditing(用于标记是否正在编辑,初始化为false)。添加完后,将newTodo重置为空字符串。

渲染待办事项

在TodoList组件中添加代码来渲染所有的待办事项。

const TodoList = () => {

    //...状态定义和添加功能函数

    return (

        

            

待办事项列表

            

            添加

            

                    {todos.map((todo) => (

                        

  • {todo.text}
  •                 ))}

                

        

    );

};

使用map函数遍历todos数组,将每个待办事项渲染为一个

  • 列表项,并使用todo.id作为key,这是 React 列表渲染的要求。

    删除待办事项功能

    为每个待办事项添加一个删除按钮,并实现删除功能。

    const TodoList = () => {

        //...状态定义和添加功能函数

        // 删除待办事项的函数

        const deleteTodo = (id) => {

            setTodos(todos.filter((todo) => todo.id!== id));

        };

        return (

            

                

    待办事项列表

                

                添加

                

                      {todos.map((todo) => (

                          

    •                         {todo.text}

                              <button onClick={() => deleteTodo(todo.id)}>删除

                          

    •                 ))}

                  

            

        );

    };

    deleteTodo函数接受一个id参数,它通过过滤todos数组,移除具有指定id的待办事项。

    编辑待办事项功能

    为每个待办事项添加一个编辑按钮,并实现编辑功能。

    const TodoList = () => {

        //...状态定义和添加功能函数

        // 切换待办事项编辑状态的函数

        const toggleEdit = (id) => {

            setTodos(

                todos.map((todo) =>

                    todo.id === id? {...todo, isEditing:!todo.isEditing } : todo

                )

            );

        };

        // 保存编辑后待办事项的函数

        const saveEdit = (id, newText) => {

            setTodos(

                todos.map((todo) =>

                    todo.id === id? {...todo, text: newText, isEditing: false } : todo

                )

            );

        };

        return (

            

                

    待办事项列表

                

                添加

                

                      {todos.map((todo) => (

                          

    •                         {todo.isEditing? (

                                  <input

                                      type="text"

                                      value={todo.text}

                                      onChange={(e) => saveEdit(todo.id, e.target.value)}

                                  />

                              ) : (

                                  {todo.text}

                              )}

                              <button onClick={() => toggleEdit(todo.id)}>

                                  {todo.isEditing? '保存': '编辑'}

                              

                              <button onClick={() => deleteTodo(todo.id)}>删除

                          

    •                 ))}

                  

            

        );

    };

    toggleEdit函数用于切换待办事项的编辑状态。当点击编辑按钮时,对应的待办事项的isEditing属性会取反。

    saveEdit函数用于保存编辑后的待办事项内容。当在编辑状态下输入新内容并点击保存时,它会更新对应待办事项的text属性,并将isEditing设置为false。

    (三)在主应用中使用 TodoList 组件

    在src/App.js文件中,导入TodoList组件并使用它。

    import React from 'react';

    import TodoList from './TodoList';

    function App() {

        return (

            

                

            

        );

    }

    export default App;

    三、个人思考

    (一)React 的优势

    组件化开发

    React 的组件化架构使得代码结构非常清晰。在待办事项列表的实现中,我们将整个功能拆分成了多个小的组件功能,如输入框、按钮、列表项等。每个组件都有自己独立的功能和状态,这样便于维护和扩展。例如,如果我们想要改变待办事项的显示样式,只需要在TodoList组件中对应的列表项渲染部分进行修改,而不会影响到其他功能。

    状态管理

    使用useState钩子来管理状态使得数据的流动和操作变得直观。在待办事项列表中,我们通过状态来存储待办事项数据和用户输入的数据。这种方式可以让我们很方便地根据用户的操作来更新数据,并且 React 会自动根据状态的变化重新渲染组件,确保界面的实时更新。

    (二)可能遇到的问题及解决方法

    列表渲染的 key 问题

    在渲染待办事项列表时,如果没有正确设置key属性,React 会给出警告。这是因为key帮助 React 识别哪些元素发生了变化。在我们的实现中,使用了待办事项的id作为key,确保了每个列表项都有唯一的标识。如果没有这个key,可能会导致列表渲染出现性能问题或者显示错误。

    状态更新的异步性

    在处理状态更新时,特别是在使用setState(在函数组件中是useState的set函数)时,需要注意其异步特性。例如,在addTodo函数中,我们不能直接依赖于setTodos之后的todos状态。如果需要基于之前的状态来更新状态,应该使用函数形式的set方法,如setTodos(prevTodos => [...prevTodos, { id: Date.now(), text: newTodo, isEditing: false }]);。

    (三)进一步优化和扩展

    本地存储

    目前,待办事项列表的数据在页面刷新后会丢失。为了改善这一点,我们可以使用浏览器的本地存储(localStorage)来保存数据。在addTodo、deleteTodo和saveEdit等函数中,添加代码来将数据同步到本地存储中,并且在组件初始化时,从本地存储中读取数据来初始化状态。

    样式优化

    从界面美观度来看,目前的待办事项列表比较简陋。可以引入 CSS 框架(如 Bootstrap 或 Material - UI)来美化界面,或者自己编写 CSS 样式来调整字体、颜色、布局等。例如,可以给待办事项列表添加一个好看的背景颜色,给按钮添加样式使其更具交互感。

    分类和排序功能

    为了提高待办事项列表的实用性,可以添加分类和排序功能。例如,用户可以将待办事项分为工作、生活、学习等类别,并且可以按照时间、优先级等进行排序。这需要在数据结构上进行扩展,在待办事项对象中添加类别和优先级等属性,并且在界面上添加相应的操作按钮和排序逻辑。

    通过以上的实践,我们可以看到 React 在实现交互性强的前端应用时具有很大的优势。通过合理的组件化设计和状态管理,能够高效地实现功能丰富的用户界面。在实际开发中,还可以根据具体需求不断地优化和扩展应用。