初学React之实现简易todolist | 豆包MarsCode AI 刷题

261 阅读4分钟

一、技术栈概述

我选择了以下技术栈:

  • React:一个用于构建用户界面的 JavaScript 库,以其高效的虚拟 DOM 更新机制著称。
  • Tailwind CSS:一个功能类优先的 CSS 框架,允许我们快速构建响应式且美观的界面。
  • Vite:一个现代化的前端构建工具,利用浏览器的 ES 模块支持,提供了快速的开发体验。

二、初始化项目

在开始之前,我们首先需要创建一个新的 Vite + React 项目。Vite 是一个现代化的前端构建工具,它利用原生 ES 模块导入,提供了快速的开发体验。以下是初始化项目的命令:

npm create vite@latest my-todo-app -- --template react
cd my-todo-app
npm install

接下来,我们安装 Tailwind CSS,这是一个功能类优先的 CSS 框架,用于快速构建界面:

npm install -D tailwindcss postcss autoprefixer
npx tailwindcss init -p

初始化 Tailwind CSS 配置文件后,我们需要在 tailwind.config.js 中配置我们的主题和样式偏好。

二、项目文件目录结构解析

  • package.json:作为项目的核心配置文件,记录了所有依赖包及其版本信息,同时定义了项目运行脚本,如npm run dev用于启动开发服务器。
  • src:项目源代码主目录,包含以下文件和子目录:
    • main.tsx:应用入口文件,负责渲染根组件并启动 React 应用。
    • index.css:全局样式文件,定义了页面布局和基本样式规则。
    • components:自定义组件存放目录,具体包括:
      • TodoList.tsx:待办事项列表组件,负责展示和管理待办事项,包括添加、编辑和删除操作。
      • TodoItem.tsx:单个待办事项组件,展示待办事项详情,并提供编辑和删除功能。
    • App.tsx:根组件,负责整合TodoList组件,可能包含全局状态管理和页面布局设置。
  • tailwind.config.js:Tailwind CSS 配置文件,用于自定义主题和样式设置。
  • vite.config.ts:Vite 配置文件,配置开发服务器、构建选项等,确保项目在不同环境下的正常运行。

三、功能实现详细步骤

首先先实现添加新待办事项

  1. TodoList.tsx中,创建输入框和添加按钮,并绑定事件处理函数。
    • 输入框允许用户输入待办事项。
    • 添加按钮的点击事件将触发addTodo函数,从输入框获取文本并添加到待办事项列表。
  2. 用户点击添加按钮或按下回车键后,待办事项被添加至状态管理,输入框清空以准备下一次输入。

确定好要实现的内容后,就可以开始写代码了

代码实现: -- TodoList.jsx

interface Todo {
  id: number;
  text: string;
}

export const TodoList: React.FC = () => {
  const [todos, setTodos] = useState<Todo[]>([]);
  const [input, setInput] = useState('');

  const addTodo = () => {
    if (input.trim()) {
      setTodos([...todos, { id: Date.now(), text: input.trim() }]);
      setInput('');
    }
  };

  const deleteTodo = (id: number) => {
    setTodos(todos.filter(todo => todo.id !== id));
  };

  const editTodo = (id: number, newText: string) => {
    setTodos(todos.map(todo =>
      todo.id === id ? { ...todo, text: newText } : todo
    ));
  };

  return (
    <div className="max-w-xl mx-auto p-6 bg-white rounded-xl shadow-lg">
      <h1 className="text-3xl font-bold text-center mb-8 text-gray-800">
        Todo List
      </h1>
      
      <div className="flex gap-3 mb-6">
        <input
          type="text"
          value={input}
          onChange={(e) => setInput(e.target.value)}
          onKeyPress={(e) => e.key === 'Enter' && addTodo()}
          placeholder="Add a new todo..."
          className="flex-1 p-3 border-2 border-gray-200 rounded-lg focus:border-blue-500 focus:ring-2 focus:ring-blue-200 transition-all duration-200 outline-none"
        />
        <button
          onClick={addTodo}
          className="px-6 py-3 bg-blue-500 text-white rounded-lg hover:bg-blue-600 active:bg-blue-700 transition-colors duration-200 flex items-center gap-2 font-medium"
        >
          <FaPlus className="text-sm" />
          Add
        </button>
      </div>

      <div className="space-y-3">
        {todos.length === 0 ? (
          <div className="text-center py-8 text-gray-500">
            No todos yet. Add one to get started!
          </div>
        ) : (
          todos.map(todo => (
            <TodoItem
              key={todo.id}
              todo={todo}
              onDelete={deleteTodo}
              onEdit={editTodo}
            />
          ))
        )}
      </div>
    </div>
  );
};
  1. 定义 Todo 接口
    • 接口定义了待办事项的属性,包括 idtext
  2. TodoList 组件
    • TodoList 是一个函数组件,使用 useState 钩子管理待办事项列表和输入框的值。
    • addTodo 函数用于添加新的待办事项。
    • deleteTodo 函数用于删除特定的待办事项。
    • editTodo 函数用于更新待办事项的文本。

然后在TodoItem中实现编辑现有待办事项

  1. TodoItem.tsx中,为编辑按钮绑定点击事件。
  2. 点击编辑按钮后,显示编辑框并填充当前待办事项文本。
  3. 用户修改内容并保存,更新待办事项文本并关闭编辑状态。

代码实现: -- TodoItem.jsx

// src/components/TodoItem.tsx
import React, { useState } from 'react';
import { FaEdit, FaTrash, FaCheck, FaTimes } from 'react-icons/fa';

interface TodoItemProps {
  todo: Todo;
  onDelete: (id: number) => void;
  onEdit: (id: number, newText: string) => void;
}

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

  const handleSubmit = () => {
    if (editText.trim()) {
      onEdit(todo.id, editText);
      setIsEditing(false);
    }
  };

  // ...其他代码
};

删除待办事项

  1. TodoItem.tsx中,为删除按钮绑定点击事件。
  2. 点击删除按钮,从待办事项列表中移除对应项。
  3. React 重新渲染列表,更新显示。

代码实现: --TodoItem.jsx

// ...在TodoItem组件内

const handleDelete = () => {
  onDelete(todo.id);
};

// ...其他代码

样式设计与交互优化

  1. 使用 Tailwind CSS 为组件添加样式,确保界面美观。
  2. 为按钮添加过渡和悬停效果,提升交互体验。
  3. 隐藏编辑和删除按钮,直到鼠标悬停在待办事项上,保持界面整洁。
  4. 显示空状态消息,引导用户添加待办事项。

成果展示

经过上面的步骤,一个简单的todolist就完成了

image.png

image.png