当前位置: 首页 > article >正文

使用React和Material-UI构建TODO应用的前端UI

使用React和Material-UI构建TODO应用的前端UI

        • 引言
        • 环境准备
        • 代码解析
          • 1. 导入必要的模块
          • 2. 创建React组件
          • 3. 定义函数
            • 3.1 获取TODO列表
            • 3.2 创建TODO项
            • 3.3 更新TODO项
            • 3.4 删除TODO项
            • 3.5 处理编辑点击事件
            • 3.6 关闭编辑对话框
            • 3.7 保存编辑内容
          • 4. 使用Effect钩子
          • 5. 渲染组件
        • 功能实现
        • 优化建议
        • 总结

引言

在现代Web开发中,TODO列表应用是一个经典的示例,用于展示如何使用前端技术构建一个简单的任务管理工具。本文将详细介绍如何使用React框架和Material-UI库来构建一个TODO列表应用,并解释代码的各个部分,帮助读者理解其工作原理。

后端API请参考,使用Express.js和SQLite3构建简单TODO应用的后端API

环境准备

在开始之前,请确保你已经安装了以下工具和库:

  1. Node.js:确保你已经安装了Node.js,可以从Node.js官网下载并安装。
  2. npm:Node.js的包管理工具,随Node.js一起安装。
  3. React:一个用于构建用户界面的JavaScript库,可以通过npm安装。
  4. Material-UI:一个基于Material Design的React组件库,同样可以通过npm安装。
  5. axios:一个基于Promise的HTTP客户端,用于处理API请求。

安装所需的依赖:

npm install react @mui/material @emotion/react @emotion/styled axios
代码解析

让我们逐步分析代码,理解每个部分的功能。

1. 导入必要的模块
import { useState, useEffect } from 'react';
import axios from 'axios';
import {TextField,Button,Checkbox,List,ListItem,ListItemText,IconButton,Dialog,DialogTitle,DialogContent,DialogActions,FormControlLabel
} from '@mui/material';
import { Delete, Edit } from '@mui/icons-material';
import { Todo } from '../types/todo';
  • React:导入useStateuseEffect钩子,用于状态管理和副作用处理。
  • axios:用于发送HTTP请求。
  • Material-UI:导入各种组件,如文本框、按钮、列表、对话框等。
  • Icons:导入删除和编辑图标。
  • Todo类型:定义TODO项的类型,确保数据的类型安全。
2. 创建React组件
export default function TodoList() {const [todos, setTodos] = useState<Todo[]>([]);const [searchTerm, setSearchTerm] = useState('');const [newTodo, setNewTodo] = useState({ title: '', description: '' });const [editingTodo, setEditingTodo] = useState<Todo | null>(null);const [editForm, setEditForm] = useState({ title: '', description: '', completed: false });
  • todos:存储TODO列表的状态。
  • searchTerm:存储搜索词的状态。
  • newTodo:存储新TODO项的状态。
  • editingTodo:存储正在编辑的TODO项的状态。
  • editForm:存储编辑表单的状态。
3. 定义函数
3.1 获取TODO列表
const fetchTodos = async () => {try {const response = await axios.get(`http://localhost:3002/api/todos?q=${searchTerm}`);setTodos(response.data);} catch (error) {console.error('Error fetching todos:', error);}
};
  • 功能:从后端获取TODO列表,支持搜索功能。
  • 实现:使用axios.get发送GET请求,根据searchTerm进行模糊搜索。
3.2 创建TODO项
const createTodo = async () => {if (!newTodo.title.trim()) return;try {await axios.post('http://localhost:3002/api/todos', newTodo);setNewTodo({ title: '', description: '' });fetchTodos();} catch (error) {console.error('Error creating todo:', error);}
};
  • 功能:创建一个新的TODO项。
  • 实现:检查标题是否为空,使用axios.post发送POST请求,创建成功后清空表单并刷新列表。
3.3 更新TODO项
const updateTodo = async (todo: Todo, isToggleComplete = false) => {try {const updatedTodo = isToggleComplete? { ...todo, completed: !todo.completed }: { ...todo, title: editForm.title, description: editForm.description, completed: editForm.completed };await axios.put(`http://localhost:3002/api/todos/${todo.id}`, updatedTodo);setEditingTodo(null);fetchTodos();} catch (error) {console.error('Error updating todo:', error);}
};
  • 功能:更新TODO项,支持标记完成和编辑内容。
  • 实现:根据isToggleComplete决定是更新完成状态还是编辑内容,使用axios.put发送PUT请求。
3.4 删除TODO项
const deleteTodo = async (id: number) => {try {await axios.delete(`http://localhost:3002/api/todos/${id}`);fetchTodos();} catch (error) {console.error('Error deleting todo:', error);}
};
  • 功能:删除指定的TODO项。
  • 实现:使用axios.delete发送DELETE请求,删除成功后刷新列表。
3.5 处理编辑点击事件
const handleEditClick = (todo: Todo) => {setEditingTodo(todo);setEditForm({title: todo.title,description: todo.description || '',completed: todo.completed});
};
  • 功能:打开编辑对话框,填充TODO项的详细信息。
  • 实现:设置editingTodoeditForm状态,显示编辑表单。
3.6 关闭编辑对话框
const handleClose = () => {setEditingTodo(null);setEditForm({ title: '', description: '', completed: false });
};
  • 功能:关闭编辑对话框,重置表单。
  • 实现:清除editingTodoeditForm状态。
3.7 保存编辑内容
const handleSave = () => {if (editingTodo && editForm.title.trim()) {updateTodo(editingTodo);}
};
  • 功能:保存编辑的内容。
  • 实现:检查标题是否为空,调用updateTodo更新TODO项。
4. 使用Effect钩子
useEffect(() => {const debounceSearch = setTimeout(() => {fetchTodos();}, 300);return () => clearTimeout(debounceSearch);
}, [searchTerm]);
  • 功能:实现搜索的防抖动效果,防止频繁请求。
  • 实现:使用setTimeout延迟300毫秒后执行fetchTodos,并在组件销毁时清除定时器。
5. 渲染组件
return (<div style={{ maxWidth: 600, margin: '0 auto', padding: '20px' }}><TextFieldfullWidthlabel="Search Todos"variant="outlined"value={searchTerm}onChange={(e) => setSearchTerm(e.target.value)}margin="normal"/><List>{todos.map((todo) => (<ListItemkey={todo.id}secondaryAction={(<><IconButton onClick={() => handleEditClick(todo)}><Edit /></IconButton><IconButton onClick={() => deleteTodo(todo.id)}><Delete /></IconButton></>)}style={{display: todo.completed ? 'none' : 'flex',opacity: todo.completed ? 0.7 : 1}}><Checkboxchecked={Boolean(todo.completed)}onChange={() => updateTodo(todo, true)}/><ListItemTextprimary={todo.title}secondary={todo.description}style={{textDecoration: todo.completed ? 'line-through' : 'none',}}/></ListItem>))}</List><div style={{ display: 'flex', gap: 10, marginBottom: 20 }}><TextFieldfullWidthlabel="New Todo Title"value={newTodo.title}onChange={(e) => setNewTodo({ ...newTodo, title: e.target.value })}/><TextFieldfullWidthlabel="Description"value={newTodo.description}onChange={(e) => setNewTodo({ ...newTodo, description: e.target.value })}/><Buttonvariant="contained"color="primary"onClick={createTodo}>Add</Button></div><Dialog open={Boolean(editingTodo)} onClose={handleClose}><DialogTitle>Edit Todo</DialogTitle><DialogContent><TextFieldautoFocusmargin="dense"label="Title"fullWidthvalue={editForm.title}onChange={(e) => setEditForm({ ...editForm, title: e.target.value })}/><TextFieldmargin="dense"label="Description"fullWidthmultilinerows={3}value={editForm.description}onChange={(e) => setEditForm({ ...editForm, description: e.target.value })}/><FormControlLabelcontrol={(<Checkboxchecked={editForm.completed}onChange={(e) => setEditForm({ ...editForm, completed: e.target.checked })}/>)}label="Completed"/></DialogContent><DialogActions><Button onClick={handleClose} color="primary">Cancel</Button><ButtononClick={handleSave}color="primary"disabled={!editForm.title.trim()}>Save</Button></DialogActions></Dialog></div>
);
  • 搜索框:允许用户输入搜索词,实时搜索TODO列表。
  • TODO列表:显示所有TODO项,每个项包含标题、描述、编辑和删除按钮,以及完成状态Checkbox。
  • 添加TODO表单:允许用户输入新TODO的标题和描述,点击“Add”按钮创建。
  • 编辑对话框:当用户点击编辑按钮时,显示编辑表单,允许修改TODO的标题、描述和完成状态。
功能实现
  1. 添加TODO项:用户输入标题和描述后,点击“Add”按钮,发送POST请求到后端,创建新的TODO项。
  2. 编辑TODO项:用户点击编辑按钮,打开编辑对话框,修改TODO项的详细信息后,点击“Save”按钮,发送PUT请求到后端,更新TODO项。
  3. 删除TODO项:用户点击删除按钮,发送DELETE请求到后端,删除指定的TODO项。
  4. 搜索TODO项:用户输入搜索词,组件会自动搜索标题或描述中包含该词的TODO项,支持防抖动功能,减少请求次数。
  5. 标记完成:用户点击Checkbox,TODO项会被标记为完成,样式会变为灰色并添加删除线。
优化建议

尽管这段代码已经可以正常工作,但为了提升应用的性能和用户体验,可以考虑以下优化:

  1. 添加加载状态:在数据加载过程中,显示加载动画,提升用户体验。
  2. 添加错误提示:在请求失败时,显示错误提示信息,帮助用户了解问题所在。
  3. 添加成功提示:在创建、更新或删除TODO项成功后,显示成功提示信息。
  4. 优化样式:根据Material Design规范,优化组件的样式和布局,提升视觉效果。
  5. 添加响应式设计:确保应用在不同设备上都能良好显示,提升应用的适应性。
  6. 添加数据验证:在前端和后端都添加数据验证,确保输入的数据合法有效。
总结

通过本文,我们详细解析了一个使用React和Material-UI构建的TODO列表应用。从状态管理、HTTP请求到组件渲染,每个部分都进行了详细的解释。希望这篇文章能够帮助读者理解如何使用这些技术构建一个简单的TODO应用,并为进一步的学习和开发打下基础。

相关文章:

使用React和Material-UI构建TODO应用的前端UI

使用React和Material-UI构建TODO应用的前端UI 引言环境准备代码解析1. 导入必要的模块2. 创建React组件3. 定义函数3.1 获取TODO列表3.2 创建TODO项3.3 更新TODO项3.4 删除TODO项3.5 处理编辑点击事件3.6 关闭编辑对话框3.7 保存编辑内容 4. 使用Effect钩子5. 渲染组件 功能实现…...

2502,索界面3

原文 SonicUI,你从未见过的方便GUI引擎-源码 介绍 SonicUI是基于原生GDIAPI的GUI引擎.它提供了几个简单的UI组件来实现高效的UI效果,如自绘按钮,不规则窗口,动画,窗口中的网径和图像操作方法. 主要目的是用最少的代码来达到最佳效果. 背景 周知,UI开发一般重复用无趣.因此…...

ChatGPT提问技巧:行业热门应用提示词案例--咨询法律知识

ChatGPT除了可以协助办公&#xff0c;写作文案和生成短视频脚本外&#xff0c;和还可以做为一个法律工具&#xff0c;当用户面临一些法律知识盲点时&#xff0c;可以向ChatGPT咨询获得解答。赋予ChatGPT专家的身份&#xff0c;用户能够得到较为满意的解答。 1.咨询法律知识 举…...

[吾爱出品]CursorWorkshop V6.33 专业鼠标光标制作工具-简体中文汉化绿色版

CursorWorkshop V6.33 专业鼠标光标制作工具 链接&#xff1a;https://pan.xunlei.com/s/VOIFeq5DFB9FS56Al_mT2EfdA1?pwd7ij4# 产品概述 Axialis CursorWorkshop 是一个专业光标创作工具它在 Windows 下运行&#xff0c;让您轻松创建高质量的静态和动态光标适用于 Windows …...

《运维:技术的基石,服务的保障》

1. LVS&#xff08;Linux Virtual Server&#xff09;&#xff1a;基于Linux内核的四层负载均衡解决方案 2. Bonding&#xff08;链路聚合&#xff09;&#xff1a;物理网卡冗余与带宽叠加技术 3. RHEL&#xff08;Red Hat Enterprise Linux&#xff09;&#xff1a;企业级Li…...

【C语言】自定义类型讲解

文章目录 一、前言二、结构体2.1 概念2.2 定义2.2.1 通常情况下的定义2.2.2 匿名结构体 2.3 结构体的自引用和嵌套2.4 结构体变量的定义与初始化2.5 结构体的内存对齐2.6 结构体传参2.7 结构体实现位段 三、枚举3.1 概念3.2 定义3.3 枚举的优点3.3.1 提高代码的可读性3.3.2 防止…...

Day25 洛谷 提高- 1007

零基础洛谷刷题记录 Day01 2024.11.18 Day02 2024.11.25 Day03 2024.11.26 Day04 2024.11.28 Day05 2024.11.29 Day06 2024 12.02 Day07 2024.12.03 Day08 2024 12 05 Day09 2024.12.07 Day10 2024.12.09 Day11 2024.12.10 Day12 2024.12.12 Day13 2024.12.16 Day14 2024.12.1…...

LabVIEW涡轮诊断系统

一、项目背景与行业痛点 涡轮机械是发电厂、航空发动机、石油化工等领域的核心动力设备&#xff0c;其运行状态直接关系到生产安全与经济效益。据统计&#xff0c;涡轮故障导致的非计划停机可造成每小时数十万元的经济损失&#xff0c;且突发故障可能引发严重安全事故。传统人…...

GGML、GGUF、GPTQ 都是啥?

GGML、GGUF和GPTQ是三种与大型语言模型(LLM)量化和优化相关的技术和格式。它们各自有不同的特点和应用场景,下面将详细解释: 1. GGML(GPT-Generated Model Language) 定义:GGML是一种专为机器学习设计的张量库,由Georgi Gerganov创建。它最初的目标是通过单一文件格式…...

Kafka 使用说明(kafka官方文档中文)

文章来源:kafka -- 南京筱麦软件有限公司 第 1 步:获取 KAFKA 下载最新的 Kafka 版本并提取它: $ tar -xzf kafka_{{scalaVersion}}-{{fullDotVersion}}.tgz $ cd kafka_{{scalaVersion}}-{{fullDotVersion}} 第 2 步:启动 KAFKA 环境 注意:您的本地环境必须安装 Java 8+。…...

Kubernetes 中 BGP 与二层网络的较量:究竟孰轻孰重?

如果你曾搭建过Kubernetes集群&#xff0c;就会知道网络配置是一个很容易让人深陷其中的领域。在负载均衡器、服务通告和IP管理之间&#xff0c;你要同时应对许多变动的因素。对于许多配置而言&#xff0c;使用二层&#xff08;L2&#xff09;网络就完全能满足需求。但边界网关…...

大模型综述一镜到底(全文八万字) ——《Large Language Models: A Survey》

论文链接&#xff1a;https://arxiv.org/abs/2402.06196 摘要&#xff1a;自2022年11月ChatGPT发布以来&#xff0c;大语言模型&#xff08;LLMs&#xff09;因其在广泛的自然语言任务上的强大性能而备受关注。正如缩放定律所预测的那样&#xff0c;大语言模型通过在大量文本数…...

物理群晖SA6400核显直通win10虚拟机(VMM)

写在前面&#xff1a;请先确保你的核显驱动支持开启SR-IOV 确保你的BIOS开启了以下选项&#xff1a; VT-D VMX IOMMU Above 4G ResizeBAR 自行通过以下命令确认支持情况&#xff1a; dmesg | grep -i iommudmesg | grep DMAR分配1个虚拟vGPU&#xff1a;echo 1 | sudo tee /sy…...

【python】tkinter实现音乐播放器(源码+音频文件)【独一无二】

&#x1f449;博__主&#x1f448;&#xff1a;米码收割机 &#x1f449;技__能&#x1f448;&#xff1a;C/Python语言 &#x1f449;专__注&#x1f448;&#xff1a;专注主流机器人、人工智能等相关领域的开发、测试技术。 【python】tkinter实现音乐播放器&#xff08;源码…...

ESP32开发工具介绍:Thonny——初学者的MicroPython利器

文章目录 引言什么是 Thonny?为什么选择 Thonny 开发 ESP32?1. **MicroPython 的天然支持**2. **极简的配置流程**3. **适合快速原型开发**如何用 Thonny 开发 ESP32?步骤 1:准备工作步骤 2:烧录 MicroPython 固件步骤 3:在 Thonny 中连接 ESP32步骤 4:编写并运行代码Th…...

进程的环境变量

export MUDUO_LOG_DEBUG1 ./testif (::getenv("MUDUO_LOG_TRACE"))return true;有时在程序运行前&#xff0c;我们希望设置环境变量。此处::表示全局命名空间。 在类 Unix 系统&#xff08;如 Linux、macOS&#xff09;中&#xff0c;环境变量并不直接存储在堆、栈或…...

Qwen2.5-Max:AI技术的新里程碑

随着人工智能&#xff08;AI&#xff09;技术的不断进步&#xff0c;全球各大科技公司都在竞相推出更强大的语言模型。近日&#xff0c;阿里巴巴发布了其最新的超大规模混合专家模型&#xff08;MoE&#xff09;——Qwen2.5-Max&#xff0c;这一成果不仅在多个基准测试中超越了…...

MyBatis-Plus速成指南:常用注解

Table Name: 概述&#xff1a; MyBatis-Plus 在确定操作的表时&#xff0c;由 BaseMapper的泛型决定&#xff0c;即实体类决定&#xff0c;且默认操作的表名和实体类的类名一致 问题&#xff1a; 如果实体类类型的类名和要操作表的表名不一致会出现什么问题&#xff1f;(把 us…...

Vue.js组件开发-Vue实现上传word模版打印设置自定义样式和布局

要使用 Vue 实现上传 Word 模板、打印并设置自定义样式和布局&#xff0c;可以借助一些工具和库来完成这个任务。 实现步骤 创建 Vue 项目&#xff1a;使用 Vue CLI 创建一个新的 Vue 项目。安装依赖&#xff1a;安装 docx-templates 库来处理 Word 模板&#xff0c;file-sav…...

Linux 压缩打包

Linux压缩打包 文章目录 Linux压缩打包压缩的意义和原理压缩的意义压缩的原理压缩与解压缩的好处 压缩打包命令.zipzip 命令用法unzip 的用法 .gzgzip 的用法gunzip 的用法 .bz2bzip2 的用法bunzip2 的用法 .xzxz 命令用法 tar 04-Linux压缩打包课后习题 压缩的意义和原理 压缩…...

RabbitMQ深度探索:前置知识

消息中间件&#xff1a; 消息中间件基于队列模式实现异步 / 同步传输数据作用&#xff1a;可以实现支撑高并发、异步解耦、流量削峰、降低耦合 传统的 HTTP 请求存在的缺点&#xff1a; HTTP 请求基于响应的模型&#xff0c;在高并发的情况下&#xff0c;客户端发送大量的请求…...

29.日常算法

1. 验证回文串 II 题目来源 给定一个非空字符串 s&#xff0c;请判断如果 最多 从字符串中删除一个字符能否得到一个回文字符串。 示例 1&#xff1a; 输入: s “aba” 输出: true 示例 2&#xff1a; 输入: s “abca” 输出: true 解释: 可以删除 “c” 字符 或者 “b” …...

智慧校园平台:构建现代化教育体系的技术支撑

在当今信息技术飞速发展的时代&#xff0c;智慧校园平台成为了现代教育领域中的重要组成部分。智慧校园平台不仅能够提升学校的管理水平&#xff0c;还能提供更为个性化和高效的教学服务&#xff0c;从而促进学生的全面发展。 数据分析是智慧校园平台的重要组成部分。通过对学生…...

【单层神经网络】基于MXNet的线性回归实现(底层实现)

写在前面 刚开始先从普通的寻优算法开始&#xff0c;熟悉一下学习训练过程下面将使用梯度下降法寻优&#xff0c;但这大概只能是局部最优&#xff0c;它并不是一个十分优秀的寻优算法 整体流程 生成训练数据集&#xff08;实际工程中&#xff0c;需要从实际对象身上采集数据…...

20250204将Ubuntu22.04的默认Dash的shell脚本更换为bash

20250204将Ubuntu22.04的默认Dash的shell脚本更换为bash 2025/2/4 23:45 百度&#xff1a;dash bash https://blog.csdn.net/2201_75772333/article/details/136955776 【Linux基础】dash和bash简介 Dash&#xff08;Debian Almquist Shell&#xff09;和 Bash&#xff08;Bou…...

Golang 并发机制-3:通道(channels)机制详解

并发编程是一种创建性能优化且响应迅速的软件的强大方法。Golang&#xff08;也称为 Go&#xff09;通过通道&#xff08;channels&#xff09;这一特性&#xff0c;能够可靠且优雅地实现并发通信。本文将揭示通道的概念&#xff0c;解释其在并发编程中的作用&#xff0c;并提供…...

Python处理数据库:MySQL与SQLite详解

Python处理数据库&#xff1a;MySQL与SQLite详解 在数据处理和存储方面&#xff0c;数据库扮演着至关重要的角色。Python提供了多种与数据库交互的方式&#xff0c;其中pymysql库用于连接和操作MySQL数据库&#xff0c;而SQLite则是一种轻量级的嵌入式数据库&#xff0c;Pytho…...

可视化大屏在石油方面的应用。

可视化大屏通过整合石油工业全链条数据&#xff0c;构建数字孪生驱动的运营监控体系&#xff0c;显著提升油气勘探、开采、储运及炼化的管理效能。其技术架构依托工业物联网&#xff08;IIoT&#xff09;实时采集钻井参数、管道压力、储罐液位等数据&#xff0c;通过OPC UA协议…...

【学术投稿-2025年计算机视觉研究进展与应用国际学术会议 (ACVRA 2025)】从计算机基础到HTML开发:Web开发的第一步

会议官网&#xff1a;www.acvra.org 简介 2025年计算机视觉研究进展与应用&#xff08;ACVRA 2025&#xff09;将于2025年2月28-3月2日在中国广州召开&#xff0c;将汇聚世界各地的顶尖学者、研究人员和行业专家&#xff0c;聚焦计算机视觉领域的最新研究动态与应用成就。本次…...

【 AI agents】letta:2024年代理堆栈演进(中英文翻译)

The AI agents stack AI 代理堆栈 November 14, 2024 11月 14, 2024原文: The AI agents stack官方教程教程学习笔记: 【memgpt】letta 课程1/2:从头实现一个自我编辑、记忆和多步骤推理的代理Understanding the AI agents landscape 了解 AI 代理环境 Although we see a …...