使用React 实现一个简单的待办事项列表 | 青训营

126 阅读9分钟

开发环境

  • 确保在本地已经下载了Node(如果没有下载,自行去官网下载安装最新版本即可),打开终端,输入 "node -v"检查是否安装成功,如下图所示即安装成功 image.png

  • 创建React应用,通常有两种常见的方式

    • Create React App(CRA)

      CRA是一个由React官方团队开发和维护的工具,它会在预配置的开发环境中设置新的React项目。使用CRA可以简单地开始构建React项目,无需担心复杂的配置。以下是使用CRA创建的简单步骤: 1.~ npx create-react-app App-Name 2.~ cd App-Name 3.~ npm start. 这将可以创建一个名为"App-Name"的新文件夹,安装所需要的依赖项,并启动开发服务器。CRA提供了基本的项目结构、开发服务器和构建脚本,让我们可以专注于编写React组件

    • Vite

      Vite是一个快速的现代构建工具,旨在优化开发体验并加快构建速度,特别适用于构建Vue.js和React应用程序。与传统的打包工具不同,Vite使用原生ES模块来提供快速开发服务器和热模块替换(HMR)。创建一个React应用使用Vite非常简单,本篇文章就会使用Vite来构建

打开终端输入"nom create vite@latest" -> y -> project name -> React -> Typescript

image.png

cd react-app -> npm i

image.png

  • "code .",进入VScode开发环境进行开发。这时候打开VScode的终端输入"npm run dev".并打开对应的URL,会弹出下图所示的窗口,代表成功配置开发环境。

image.png

React简单介绍

React 是一个由 Facebook 开发的 JavaScript 库,用于构建用户界面。它旨在帮助开发者构建高效、可维护的大型 Web 应用程序,尤其是那些需要频繁更新和交互的应用。以下本篇笔记需要的知道的关于 React 的一些关键特点和概念:

  1. 组件化开发: React 引入了组件化开发的概念,允许开发者将用户界面划分为独立的、可重用的组件。每个组件都有自己的状态和属性,使得代码更加模块化、可维护,并且能够更好地分工合作。
  2. 虚拟 DOM: React 使用虚拟 DOM(Virtual DOM)来优化页面的更新效率。虚拟 DOM 是一个轻量级的表示真实 DOM 的 JavaScript 对象树,React 使用它来比较前后两次状态的差异,并最小化实际 DOM 操作,从而提升性能。
  3. Hooks: Hooks 是 React 16.8 版本引入的特性,它允许开发者在不编写 class 组件的情况下使用状态和其他 React 特性。Hooks 提供了一种更简洁、更可预测的方式来管理组件的状态和副作用。
  4. 状态管理: 对于复杂的应用,状态管理是一个重要的问题。React 并没有内置的全局状态管理解决方案,但它与许多第三方状态管理库(如 Redux、MobX)很好地集成,开发者可以根据应用需求选择合适的状态管理工具。
  5. JSX: JSX 是一种 JavaScript 的扩展语法,允许开发者在 JavaScript 代码中编写类似于 HTML 的标记。这使得组件的结构和外观更加直观,并且能够在开发过程中更好地表达 UI。

总之,React 是一个强大且灵活的库,使开发者能够构建现代、高效且可维护的用户界面。它的组件化、虚拟 DOM、声明式编程和状态管理等特性使得构建复杂的 Web 应用变得更加简单和可控。

实现

当我们创建一个React应用时,我们通常会将应用划分为不同的组件(component),以便更好地管理代码、复用逻辑和维护应用。这里我们希望创建一个待办事项列表,可以分为两个核心组件:TodoItemTodoList。让我对这两个组件的逻辑进行详细解释:

  1. TodoItem

该组件表示代办事项的条目,设计为以下功能:

  • 显示待办事项内容
  • 允许编辑待办事项
  • 允许删除待办事项

首先定义一个TypeScript接口,定义TodoItem的属性。这里设置了todoonEditonDelete属性。

interface TodoItemProps {
  todo: string;
  onEdit: (newTodo: string) => void;
  onDelete: () => void;
}
  • isEditing 状态用于跟踪当前是否正在编辑待办事项。

  • editedTodo 状态用于跟踪编辑中的待办事项内容。

  • handleEditClick 函数在编辑按钮点击时触发,将 isEditing 状态设置为 true

  • handleSaveClick 函数在保存按钮点击时触发,调用 onEdit 回调来更新待办事项内容,然后将 isEditing 状态设置为 false

代码如下:

const TodoItem: React.FC<TodoItemProps> = ({ todo, onEdit, onDelete }) => {
  const [isEditing, setIsEditing] = useState(false);
  const [editedTodo, setEditedTodo] = useState(todo);

  const handleEditClick = () => {
    setIsEditing(true);
  };

  const handleSaveClick = () => {
    onEdit(editedTodo);
    setIsEditing(false);
  };

最后的返回页面,根据编辑状态的不同,展示不同的内容:如果正在编辑,显示一个输入框和保存按钮,否则显示待办事项内容以及编辑和删除按钮。代码如下:

  return (
    <div className="todo-item">
      {isEditing ? (
        <div>
          <input
            type="text"
            value={editedTodo}
            onChange={(e) => setEditedTodo(e.target.value)}
          />
          <button onClick={handleSaveClick}>Save</button>
        </div>
      ) : (
        <div>
          <span>{todo}</span>
          <button onClick={handleEditClick}>Edit</button>
          <button onClick={onDelete}>Delete</button>
        </div>
      )}
    </div>
  );
};

不要忘了最后export default TodoItem;

  1. TodoList

该组件是整个待办事项列表的容器,它有以下功能:

  • 显示待办事项列表。
  • 允许添加新的待办事项。
  • 传递编辑和删除功能给 TodoItem 组件。
import React, { useState } from 'react';
import TodoItem from './TodoItem';

const TodoList: React.FC = () => {
  const [todos, setTodos] = useState<string[]>([]);
  
  const handleAddTodo = () => {
    const newTodo = prompt('Enter a new todo:');
    if (newTodo) {
      setTodos([...todos, newTodo]);
    }
  };

  const handleEditTodo = (index: number, newTodo: string) => {
    const updatedTodos = [...todos];
    updatedTodos[index] = newTodo;
    setTodos(updatedTodos);
  };

  const handleDeleteTodo = (index: number) => {
    const updatedTodos = todos.filter((_, i) => i !== index);
    setTodos(updatedTodos);
  };

  return (
    <div className="todo-list">
      <button onClick={handleAddTodo}>Add Todo</button>
      {todos.map((todo, index) => (
        <TodoItem
          key={index}
          todo={todo}
          onEdit={(newTodo) => handleEditTodo(index, newTodo)}
          onDelete={() => handleDeleteTodo(index)}
        />
      ))}
    </div>
  );
};

export default TodoList;


  • todos 状态用于存储待办事项列表。
  • handleAddTodo 函数在“添加待办事项”按钮点击时触发,通过 prompt 获取新的待办事项内容,并将其添加到 todos 状态中。
  • handleEditTodo 函数在 TodoItem 组件中的编辑保存按钮点击时触发,它会更新指定索引处的待办事项内容。
  • handleDeleteTodo 函数在 TodoItem 组件中的删除按钮点击时触发,它会从 todos 中移除指定索引处的待办事项。
  • 通过 .map() 函数遍历 todos 数组,为每个待办事项渲染一个 TodoItem 组件,并将相应的编辑和删除功能传递给子组件。
  • 点击“添加待办事项”按钮后,新的待办事项将会被添加到 todos 数组中,并触发重新渲染。

总结

TodoItem 组件

TodoItem 组件用于显示单个待办事项的内容,并提供编辑和删除功能。以下是它的详细解释:

  1. 组件属性 (TodoItemProps)

    • todo: string:这是一个字符串,表示待办事项的内容。
    • onEdit: (newTodo: string) => void:这是一个回调函数,当用户编辑待办事项并保存时调用。它将接收一个新的待办事项内容作为参数。
    • onDelete: () => void:这是一个回调函数,当用户删除待办事项时调用。
  2. 状态管理

    • isEditing: boolean:一个布尔值,表示当前待办事项是否正在编辑状态。
    • editedTodo: string:一个字符串,表示当前编辑中的待办事项内容。
  3. 编辑与保存

    • 当用户点击编辑按钮时,handleEditClick 函数会将 isEditing 状态设置为 true,从而切换到编辑模式。
    • 当用户在编辑模式下编辑待办事项并点击保存按钮时,handleSaveClick 函数会调用 onEdit 回调,并将新的待办事项内容传递给父组件,然后将 isEditing 状态设置为 false,退出编辑模式。
  4. 渲染根据编辑状态变化

    • 如果当前正在编辑,渲染一个包含输入框和保存按钮的区域,用户可以编辑并保存内容。
    • 如果不在编辑状态,渲染一个包含待办事项内容、编辑按钮和删除按钮的区域。

TodoList 组件

TodoList 组件是整个待办事项列表的容器,它负责管理多个待办事项条目并提供添加新待办事项的功能。以下是它的详细解释:

  1. 状态管理

    • todos: string[]:一个字符串数组,表示待办事项列表。
  2. 添加新待办事项

    • handleAddTodo 函数会在用户点击 "Add Todo" 按钮时触发。它通过 prompt 获取用户输入的新待办事项内容,并将其添加到 todos 数组中。
  3. 编辑与删除

    • handleEditTodo 函数用于编辑某个索引处的待办事项内容。它接收索引和新的待办事项内容作为参数,更新相应位置的 todos 数组。
    • handleDeleteTodo 函数用于删除某个索引处的待办事项。它通过过滤掉特定索引的方式更新 todos 数组。
  4. 渲染待办事项列表

    • 使用 .map() 函数遍历 todos 数组,为每个待办事项创建一个 TodoItem 组件,并传递相应的待办事项内容、编辑和删除回调函数作为属性。

总的来说,这两个组件的协同工作使用户能够管理待办事项列表。TodoItem 组件管理单个待办事项的显示、编辑和删除操作,而 TodoList 组件管理整个待办事项列表的显示、添加、编辑和删除。这种分离的设计使代码更加清晰,并且易于测试和维护。通过这个应用示例,你可以更好地理解如何在React中创建复杂应用中的可重用组件。

延申

完成上面所讨论的内容,只是完成了最简单的功能设计,我们还可以使用GORM连接数据库(使用GORM连接数据库是相对简单的,它提供了一种更高级的方式来操作数据库,隐藏了大部分底层的SQL操作),进行前后端协同,我也将在后面专门写一篇GORM连接数据库的笔记,敬请期待。除此之外,我们还可以使用Bootstrap对网页的UI做一个美化,使网页更加赏心悦目,如果有时间也会单独出一篇笔记使用Bootsrap美化本篇笔记中实现的待办事项列表网站。