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

React删除评论逻辑:1、客户端立即更新UI(乐观更新)2、后台调用删除评论API

https://gitee.com/arnold_s/my-learning-test/blob/master/20250520_reactTest/01_easyReact/react-basic_pro/src/App_Day1-14.%E8%AF%84%E8%AE%BA%E6%A1%88%E4%BE%8B-%E5%88%A0%E9%99%A4%E5%8A%9F%E8%83%BD%E5%AE%9E%E7%8E%B0.js

文章目录

  • 原代码
  • 问:为什么删除评论是客户端调用过滤评论,而不是请求数据库删除,然后再从数据库获取最新评论列表呢?
    • 当前代码的实现方式(本地状态管理)
    • 两种方式的对比
      • 1. **本地过滤方式**(当前代码)
      • 2. **API删除方式**(你提到的方式)
    • 实际项目中的最佳实践
    • 总结

原代码

import './App.scss'
import avatar from './images/bozai.png'
import { useState } from 'react'/*** 评论列表的渲染和操作** 1. 根据状态渲染评论列表* 2. 删除评论*/// 评论列表数据
const defaultList = [{// 评论idrpid: 3,// 用户信息user: {uid: '13258165',avatar: '',uname: '周杰伦',},// 评论内容content: '哎哟,不错哦',// 评论时间ctime: '10-18 08:15',like: 88,},{rpid: 2,user: {uid: '36080105',avatar: '',uname: '许嵩',},content: '我寻你千百度 日出到迟暮',ctime: '11-13 11:29',like: 88,},{rpid: 1,user: {uid: '30009257',avatar,uname: '黑马前端',},content: '学前端就来黑马',ctime: '10-19 09:00',like: 66,},
]
// 当前登录用户信息
const user = {// 用户iduid: '30009257',// 用户头像avatar,// 用户昵称uname: '黑马前端',
}/*** 导航 Tab 的渲染和操作** 1. 渲染导航 Tab 和高亮* 2. 评论列表排序*  最热 => 喜欢数量降序*  最新 => 创建时间降序*/// 导航 Tab 数组
const tabs = [{ type: 'hot', text: '最热' },{ type: 'time', text: '最新' },
]// 2、使用useEffect 监听评论列表数据的变化
// 3、使用useRef 管理评论列表的滚动位置
// 4、使用useCallback 管理评论列表的滚动位置
// 5、使用useMemo 管理评论列表的滚动位置
// 6、使用useContext 管理评论列表的滚动位置
// 7、使用useReducer 管理评论列表的滚动位置const App = () => {// 渲染评论列表// 1、使用useState 管理评论列表数据const [commentList, setCommentList] = useState(defaultList)// 删除评论const handleDelete = (rpid) => {// 过滤掉要删除的评论// 使用filter 方法过滤掉要删除的评论// filter 方法会返回一个新数组,新数组中不包含要删除的评论// 新数组中的元素是原数组中除了要删除的评论以外的所有元素// 使用setCommentList 方法更新评论列表数据setCommentList(commentList.filter(item => item.rpid !== rpid))}return (<div className="app">{/* 导航 Tab */}<div className="reply-navigation"><ul className="nav-bar"><li className="nav-title"><span className="nav-title-text">评论</span>{/* 评论数量 */}<span className="total-reply">{10}</span></li><li className="nav-sort">{/* 高亮类名: active */}<span className='nav-item'>最新</span><span className='nav-item'>最热</span></li></ul></div><div className="reply-wrap">{/* 发表评论 */}<div className="box-normal">{/* 当前用户头像 */}<div className="reply-box-avatar"><div className="bili-avatar"><img className="bili-avatar-img" src={avatar} alt="用户头像" /></div></div><div className="reply-box-wrap">{/* 评论框 */}<textareaclassName="reply-box-textarea"placeholder="发一条友善的评论"/>{/* 发布按钮 */}<div className="reply-box-send"><div className="send-text">发布</div></div></div></div>{/* 评论列表 */}<div className="reply-list">{/* 评论项 */}{commentList.map(item => (<div key={item.rpid} className="reply-item">{/* 头像 */}<div className="root-reply-avatar"><div className="bili-avatar"><imgclassName="bili-avatar-img"alt=""src={item.user.avatar|| 'https://cdn.jsdelivr.net/gh/twitter/twemoji@14.0.2/assets/72x72/1f464.png'}/></div></div><div className="content-wrap">{/* 用户名 */}<div className="user-info"><div className="user-name">{item.user.uname}</div></div>{/* 评论内容 */}<div className="root-reply"><span className="reply-content">{item.content}</span><div className="reply-info">{/* 评论时间 */}<span className="reply-time">{item.ctime}</span>{/* 评论数量 */}<span className="reply-time">点赞数:{item.like}</span>{/* 删除按钮 */}{/* 判断是否是当前登录用户 */}{item.user.uid === user.uid && (<span className="delete-btn" onClick={() => handleDelete(item.rpid)}>删除</span>)}</div></div></div></div>))}</div></div></div>)
}export default App

问:为什么删除评论是客户端调用过滤评论,而不是请求数据库删除,然后再从数据库获取最新评论列表呢?

这是一个很好的问题!让我来解释一下这两种删除评论的实现方式:

当前代码的实现方式(本地状态管理)

const handleDelete = (rpid) => {setCommentList(commentList.filter(item => item.rpid !== rpid))
}

这种方式是客户端状态管理,直接修改本地的状态数据。

两种方式的对比

1. 本地过滤方式(当前代码)

优点:

  • 🚀 响应速度快 - 无需等待网络请求
  • 💰 节省服务器资源 - 减少API调用次数
  • 🎯 用户体验好 - 立即反馈,无加载等待

缺点:

  • ⚠️ 数据不同步 - 只是前端展示删除,后端数据库还存在
  • 🔄 页面刷新后恢复 - 数据会重新从服务器加载

2. API删除方式(你提到的方式)

const handleDelete = async (rpid) => {try {// 1. 调用删除APIawait deleteCommentAPI(rpid)// 2. 重新获取评论列表const newList = await getCommentsAPI()setCommentList(newList)} catch (error) {console.error('删除失败:', error)}
}

优点:

  • 数据真实同步 - 前后端数据一致
  • 🔒 数据持久化 - 删除后数据真正消失

缺点:

  • 🐌 响应较慢 - 需要等待两次网络请求
  • 💸 服务器负担重 - 每次操作都需要API调用

实际项目中的最佳实践

在真实项目中,通常会采用混合方式

const handleDelete = async (rpid) => {try {// 1. 立即更新UI(乐观更新)setCommentList(commentList.filter(item => item.rpid !== rpid))// 2. 后台调用删除APIawait deleteCommentAPI(rpid)// 3. 如果删除失败,恢复UI状态} catch (error) {// 恢复删除的评论setCommentList(originalList)alert('删除失败,请重试')}
}

总结

当前代码可能是:

  1. 学习Demo - 专注于React状态管理学习
  2. 原型阶段 - 还未连接后端服务
  3. 离线应用 - 数据只在本地存储

在实际生产环境中,建议使用乐观更新的方式,既保证用户体验,又确保数据一致性!

相关文章:

  • Flutter setState() 状态管理详细使用指南
  • 一键实现全站多语言化:translate.js 极简集成指南,支持Vue 、React 框架。
  • 《HarmonyOSNext属性动画实战手册:让UI丝滑起舞的魔法指南》
  • 深度学习小项目合集之音频语音识别
  • 【粤语ASRTTS】粤语语音识别与合成:重塑粤语智能化标杆
  • 通过flv.js在网页中拉流进行视频播放
  • SAP RESTFUL接口方式发布SICF实现全路径
  • 【Vue】组件及组件化, 组件生命周期
  • enumerable 和 configurable 属性详解
  • 海康对接摄像头
  • Docker快速构建并启动Springboot程序,快速发布和上线/
  • 前端基础知识ES6系列 - 03(数组新增了哪些扩展)
  • 论文阅读:强化预训练
  • html打印合同模板
  • 人工智能AI
  • 《零基础读懂新能源汽车》——V2G/电池梯次利用/氢能源生态级技术拆解与商业预言
  • Java八股文——Spring「SpringBoot 篇」
  • 全连接层和卷积层
  • 学习threejs,使用TSL计算粒子鼠标特效
  • 【AI时代速通QT】第一节:C++ Qt 简介与环境安装
  • wordpress设置静态/优化网站关键词优化
  • 做石油期货看什么网站/吉安seo招聘
  • 手机视频网站建设/宁波营销型网站建设优化建站
  • 深圳品牌网站建设服务/郑州优化网站关键词
  • 华为云免费服务器/广州seo关键词优化是什么
  • 兖州中材建设有限公司网站/营销型网站建设解决方案