【react案例】实现评论列表

1. 需求

在这里插入图片描述

  1. 展示评论列表
  2. 实现删除功能
    2.1 只有自己的评论才展示删除按钮
    2.2 点击删除按钮,删除当前评论
  3. tab切换(点击对应tab,对tab文案高亮处理)
  4. 评论高亮
  5. 评论排序(最新、最热)

2. 实现思路

  1. useState维护评论列表
  2. map方法遍历渲染
  3. 删除显示——条件渲染
  4. 删除功能——拿到当前评论项的id,然后对原有评论列表进行过滤,根据id剔除要删除的评论项
  5. tab高亮——记录点击的tab的type,根据type去匹配高亮样式
  6. 评论排序——根据tab的type对评论列表状态数据进行不同的排序处理,当成新值传给set方法重新渲染视图UI(注意:排序后不要修改评论列表状态数据的原始值,教程里推荐使用lodash包的orderBy方法)

3. 代码

  • 样式是我自己随便写的,具体可以参考b站本身的css样式
3.1 App.js
import { useState } from "react"
import _ from 'lodash'
import './App.css'function App() {// 评论列表const initReviewList = [{rid: 2,user: {uid: '002',avator: 'https://tse4-mm.cn.bing.net/th/id/OIP-C.gC14cncyeUsZYKNwXOyBtgHaHa?rs=1&pid=ImgDetMain',uname: '小猫爱吃鱼'},content: '喵喵喵',ctime: '09-22 17:55',like: 90},{rid: 1,user: {uid: '001',avator: 'https://tse4-mm.cn.bing.net/th/id/OIP-C.qCys2C8LjF8c3_UHbGOooAAAAA?rs=1&pid=ImgDetMain',uname: '小狗爱吃骨头'},content: '汪汪汪',ctime: '09-22 14:55',like: 100},{rid: 0,user: {uid: '000',avator: 'https://tse4-mm.cn.bing.net/th/id/OIP-C.pL9aeO50HMujMSzGcOPhKwAAAA?rs=1&pid=ImgDetMain',uname: '二郎神'},content: '666',ctime: '09-30 12:23',like: 88}]// 当前登录的用户信息const user = {uid: '000',avator: 'https://tse4-mm.cn.bing.net/th/id/OIP-C.pL9aeO50HMujMSzGcOPhKwAAAA?rs=1&pid=ImgDetMain',uname: '二郎神'}// tabconst tabs = [{type: 'hot',text:'最热',},{type: 'new',text:'最新',}]const [reviewList, setReviewList] = useState(_.orderBy(initReviewList, 'like', 'desc'))function handleDeleteReview(currentRid) {setReviewList(reviewList.filter(item=> item.rid !== currentRid))}const [currTabType, steCurrTabType] = useState('hot')function handleClickTab(type) {steCurrTabType(type)if (type === 'hot') {// 根据点赞数量,降序排序setReviewList(_.orderBy(reviewList, 'like', 'desc'))} else {// 根据评论时间,降序排序setReviewList(_.orderBy(reviewList, 'ctime', 'desc'))}}return (<div className="App">{/* 导航栏 */}<div className="review-header">{/* 标题 */}<div className="review-title-container"><span className="review-title">评论</span>{/* 评论总数 */}<div className="review-total">{reviewList.length ?? 0}</div></div><div className="review-tabs-container">{tabs.map((item, index) => {return <div key={item.type} className="tabs-item"><span className={`tabs-text ${item.type === currTabType && 'tabs-active'}`} onClick={() => handleClickTab(item.type)}>{item.text}</span>{index < tabs.length - 1 && <div className="tabs-idot">|</div>}</div>})}</div></div>{/* 评论 */}<div className="review-wrap">{/* 发表评论 */}<div className="box-normal"><img className="normal-avator" src={user.avator}></img><input className="review-input" placeholder="发一条友善的评论"></input><button className="add-review">发布</button></div>{/* 评论列表 */}<div className="review-list">{reviewList.map((item) => {{/* 每一条评论 */ }return <div className="review-item" key={item.rid}>{/* 头像 */}<img className="review-avator" src={item.user.avator}></img><div className="review-item-content">{/* 用户名 */}<div className="user-name">{item.user.uname}</div>{/* 评论内容 */}<span className="review-content">{item.content}</span>{/* 评论相关信息 */}<div className="review-msg">{/* 评论时间 */}<span className="review-date">{item.ctime}</span>{/* 点赞数量 */}<span className="good-count">点赞数:{item.like}</span>{/* 删除评论按钮 */}{item.user.uid === user.uid && <span className="review-delete" onClick={() => handleDeleteReview(item.rid)}>删除</span>}</div>{/* 分割线 */}<div className="part-line"></div></div></div>})}</div></div></div>);
}export default App;
3.2 App.css
.review-header {display: flex;.review-title-container {display: flex;align-items: center;margin-right: 40px;.review-title {font-weight: bold;margin-right: 2px;}.review-total {font-size: 12px;color: gray;}}.review-tabs-container {display: flex;align-items: center;font-size: 12px;font-weight: bold;.tabs-item {color: gray;display: flex;.tabs-text {cursor: pointer;}.tabs-active {color: black;}.tabs-idot {margin: 0px 5px;}}}
}.box-normal {display: flex;margin: 16px 0px 30px 0px;.normal-avator {width: 50px;height: 50px;border-radius: 50%;margin-right: 20px;}.review-input {border: 1px solid #F1F2F3;background-color: #F1F2F3;border-radius: 6px;padding-left: 10px;}.add-review {background-color: skyblue;border: transparent;border-radius: 6px;color: #fff;margin-left: 6px;padding: 0px 10px;}
}.review-list {.review-item {display: flex;margin-bottom: 15px;.review-avator {width: 50px;height: 50px;border-radius: 50%;margin-right: 20px;}.review-item-content {.user-name {font-size: 12px;font-weight: bold;color: gray;margin-bottom: 6px;}.review-content {font-size: 14px;}.review-msg {font-size: 10px;color: gray;.review-date {margin-right: 15px;}.good-count {margin-right: 15px;}.review-delete {cursor: pointer;}}.part-line {margin-top: 5px;height: 0.5px;background-color: #E3E5E7;}}}
}
3.3 效果图

在这里插入图片描述

参考

黑马程序员react教程

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/432922.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【小程序】uniapp自定义图标组件可动态更换svg颜色

组件描述 通过图标名称加载对应svg&#xff0c;size参数调整图标大小&#xff0c;color参数调整图标颜色 解决思路&#xff1a; 存svg获svg&#xff0c;对象方式正则替换svg的fill值&#xff0c;不改变源文件&#xff0c;通过base64直接加载缓存svg源文件&#xff0c;避免重…

Android 通过自定义注解实现Activity间跳转时登录路由的自动拦截

应用场景 在Android 中部分软件需要登录才能使用&#xff0c;但是有的页面又不需要登录&#xff0c;Android不同于Web可以直接拦截重定向路由&#xff0c;因此如果在Android中如果需要检测是否登录&#xff0c;如果没登录跳转登录的话就需要再每个页面中判断&#xff0c;当然也…

Leetcode面试经典150题-39.组合总和

给你一个 无重复元素 的整数数组 candidates 和一个目标整数 target &#xff0c;找出 candidates 中可以使数字和为目标数 target 的 所有 不同组合 &#xff0c;并以列表形式返回。你可以按 任意顺序 返回这些组合。 candidates 中的 同一个 数字可以 无限制重复被选取 。如…

高级算法设计与分析 学习笔记9 跳表

单链表的样子我们很熟悉了&#xff1a; 怎么加快查找&#xff1f;&#xff1a; 查找的具体方法&#xff1a; 超过了就回头下去。 这条“快速路”最好是几个节点呢&#xff1f;&#xff1a; 假如我们弄好多层跳表呢&#xff1f;&#xff1a; 给弄成2叉树了&#xff01; 如何插入…

堆的数组实现

目录 一、堆 二叉树的顺序结构 堆的概念及结构 1.概念 2.堆的分类 (1)大堆 (2)小堆 二、利用数组(顺序结构)实现堆的过程 1.利用数组实现堆的思路 2.堆是用数组实现的&#xff0c;在数组中通过双亲找自己左右孩子、通过左右孩子找自己双亲的思路 2.1.思路 2.2.孩子与…

【YashanDB知识库】YMP迁移oracle不兼容给用户授权高级包

本文转自YashanDB官网&#xff0c;具体内容请见https://www.yashandb.com/newsinfo/7441382.html?templateId1718516 【标题】YMP迁移oracle不兼容给用户授权高级包 【关键字】oracle迁移&#xff0c;高级包授权 【问题描述】迁移评估任务中&#xff0c;oracle迁移YashanDB…

FOC电机驱动开发踩坑记录

关键技术 SVPWM电机磁场控制电流采样park变换和Clark变换滑膜观测器&#xff08;无感FOC&#xff09; SVPWM电机磁场控制 SVPWM主要思想是通过精确的对UVW三相电流的分时控制&#xff0c;来控制转子的合成力矩&#xff0c;达到目标方向&#xff0c;常用的是6分区的设计&…

RabbitMQ 高级特性——重试机制

文章目录 前言重试机制配置文件设置生命交换机、队列和绑定关系生产者发送消息消费消息 前言 前面我们学习了 RabbitMQ 保证消息传递可靠性的机制——消息确认、持久化和发送发确认&#xff0c;那么对于消息确认和发送方确认&#xff0c;如果接收方没有收到消息&#xff0c;那…

C++类和对象——第二关

目录 类的默认成员函数&#xff1a; &#xff08;一&#xff09;构造函数 &#xff08;二&#xff09;析构函数 &#xff08;三&#xff09;拷贝构造函数 类的默认成员函数&#xff1a; 类里面有6个特殊的成员函数分别包揽不同的功能; &#xff08;一&#xff09;构造函数…

极狐GitLab 17.4 升级指南

GitLab 是一个全球知名的一体化 DevOps 平台&#xff0c;很多人都通过私有化部署 GitLab 来进行源代码托管。极狐GitLab https://dl.gitlab.cn/6y2wxugm 是 GitLab 在中国的发行版&#xff0c;专门为中国程序员服务。可以一键式部署极狐GitLab。 本文分享极狐GitLab 17.4 升级…

老人跌倒扶不扶?涪城三职工给出响亮答案

一、关键时刻的选择 于绵阳市三江湖湿地公园&#xff0c;平凡午后&#xff0c;三名环卫人员刘后刚、严荣礼及杨树坤正紧张作业。突闻呼救声&#xff0c;一位老人在石阶上跌倒需援手。在紧急关头&#xff0c;他们果断抛却工具&#xff0c;疾速赶至老人身边。此举不仅展现了他们…

MySQL数据库进阶知识(四)《视图、存储过程、触发器》

学习目标&#xff1a; 掌握数据库视图基础知识 掌握数据库存储过程原理 掌握数据库触发器相关知识 学习内容&#xff1a; 一. 视图 介绍 视图&#xff08;View&#xff09;是一种虚拟存在的表。视图中的数据并不在数据库中实际存在&#xff0c;行和列数据来自定义视图的查询…

JPEG图像的DCT(Discrete Cosine Transform)变换公式代码详解

引 言 网络上图像在传输过程中为节省内存空间主要采用jpeg格式。jpeg图属于有损压缩图像的一种。在图像篡改检测过程中&#xff0c;可以利用jpeg图像的单双压缩伪影的不同而判别图像为伪造图并可以定位伪造区域。RGB图像变成jpeg图像过程中涉及从RGB图变成YCbCr图像&#xff0c…

FreeRTOS(四)FreeRTOS列表与列表项

目录 列表 列表项 迷你列表项 列表和列表项的关系 列表相关API函数 列表初始化 列表项初始化 列表项插入 列表项末尾插入 列表项删除 列表遍历 在 FreeRTOS 中&#xff0c;列表&#xff08;List&#xff09;和列表项&#xff08;ListItem&#xff09;是核心数据结构&…

Centos7系统根分区空间小home空间大如何增加分区

Centos7 默认安装&#xff0c;区划默认划分&#xff0c;用着怎么感觉有问题&#xff0c;根分区太小50G&#xff0c;而home分区太大。 如果处理&#xff0c;能扩大根分区呢&#xff1f;如果是新安装的&#xff0c;可以先删除home&#xff0c;然后再扩容 根分区。最后使其生效。…

计算机视觉硬件整理(四):相机与镜头参数介绍

文章目录 前言一、工业相机常用分类二、工业相机的基本参数三、工业相机的接口四、工业镜头的参数五、工业镜头的选择要点 前言 随着科技的飞速发展&#xff0c;工业自动化和智能制造在当今社会扮演着越来越重要的角色。在这个背景下&#xff0c;工业相机作为一种关键的视觉检…

Qualitor processVariavel.php 未授权命令注入漏洞复现(CVE-2023-47253)

0x01 漏洞概述 Qualitor 8.20及之前版本存在命令注入漏洞,远程攻击者可利用该漏洞通过PHP代码执行任意代码。 0x02 复现环境 FOFA&#xff1a;app"Qualitor-Web" 0x03 漏洞复现 PoC GET /html/ad/adpesquisasql/request/processVariavel.php?gridValoresPopHi…

【azure-openai】批量翻译demo【python】【gradio】

要求&#xff1a;拥有azure-openai-api&#xff0c;上传文件为csv格式&#xff0c;utf-8编码。 注意&#xff1a;如果出现乱码&#xff0c;重新运行&#xff0c;换种方式打开&#xff0c;有时候wps会自动改编码。 实现功能&#xff1a;选择语言&#xff0c;使用gpt4omini&…

使用docker形式部署prometheus+alertmanager+钉钉告警

一、拉取所需要的镜像 docker pull prom/node-exporter docker pull grafana/grafana docker pull prom/prometheus docker pull prom/alertmanager 其中 prom/node-exporter&#xff1a;用于收集主机系统信息和指标的 grafana/grafana&#xff1a;是一个用于可视化和分…

mac 上配置Jmeter代理进行web脚本录制过程容易踩坑的点

macOS 配置 Jmeter代理录制web脚本&容易踩坑的点 mac配置下载&#xff1a;前景提要&#xff1a;Jmeter中具体操作容易踩坑的点1、进入浏览器后&#xff0c;显示访问连接不安全。2、证书失效需要重新生成3、重新生成证书的方式4、没有生成新的证书5、jmeter安装路径找不到 m…