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

React:B站评论demo,实现列表渲染、删除按钮显示和功能实现、导航栏渲染切换及高亮显示、评论区的排序

功能要求:

1、渲染评论列表

2、删除评论功能:只显示自己评论的删除按钮;点击删除按钮,删除当前评论,列表中不再显示。

3、渲染导航Tab(最新 | 最热)和其 高亮实现

4、评论排序功能实现(最新:按时间排序 | 最热:按点赞数排序)

核心思路:

1、使用map方法对列表数据进行遍历渲染(别忘记加key)

2、使用useState维护评论列表

3、只显示自己评论删除按钮,应当是一个条件渲染

4、删除功能:点击删除按钮时,传出唯一匹配项 id,以id为条件对评论列表做 filter过滤。判断当前登录用户信息当中的uid 和 评论数据当中的uid 一样时,才显示这条评论的删除按钮(user.id === item.user.id)

5、Tab功能实现:点击谁就把谁的 type(独一无二的标识)记录下来,然后和遍历时的每一项的type 做匹配,谁匹配到就设置负责高亮的类名。

6、评论区按序排列,用到了lodash库的排序函数

源码 以及 详细代码注释 如下: 

// App.jsimport './App.scss'
import jayAvatar from './images/jay.png'
import ljAvatar from './images/lj.png'
import xsAvatar from './images/xs.png'
import React, { useState } from 'react'
import _ from 'lodash'// 评论列表的渲染和操作 1. 根据状态渲染评论列表 2. 删除评论// 评论列表数据
const defaultList = [{// 评论idrpid: 3,// 用户信息user: {uid: '13258165',avatar: jayAvatar,uname: '周杰伦',},// 评论内容content: '哎哟,不错哦',// 评论时间ctime: '10-18 08:15',like: 989,},{rpid: 2,user: {uid: '36080105',avatar: xsAvatar,uname: '许嵩',},content: '我寻你千百度 日出到迟暮',ctime: '11-13 11:29',like: 88,},{rpid: 1,user: {uid: '30009257',avatar: ljAvatar,uname: '李健',},content: '只是因为在人群中多看了你一眼',ctime: '10-19 09:00',like: 66,},
]
// 当前登录用户信息
const user = {// 用户iduid: '30009257',// 用户头像avatar: jayAvatar,// 用户昵称uname: '李健',
}// 导航 Tab 的渲染和操作  1. 渲染导航 Tab 和高亮  2. 评论列表排序// 导航 Tab 数组
const tabs = [{ type: 'hot', text: '最热' },{ type: 'time', text: '最新' },
]const App = () => {// 使用useState管理评论列表,默认值为按照点赞数降序的defaultList(使用lodash库的orderBy方法)const [commentList, setCommentList] = useState(_.orderBy(defaultList, ['like'], ['desc']))// 评论删除功能const handleDel = (id) => {console.log(id)// 对commentList进行过滤,过滤掉id等于传入id的评论,留下id不等于传入id的评论setCommentList(commentList.filter(item => item.rpid !== id))}// tab切换功能// 1. 点击谁就把谁的唯一标识type记录下来// 2. 通过记录的type和每一项遍历时的type做匹配 控制激活类名的显示const [type, setType] = useState('hot')const handleTabChange = (type) => {console.log(type)setType(type)// 基于列表的排序if (type === 'hot') {// 最热 => 喜欢点赞数量降序// lodash函数库,desc降序排序setCommentList(_.orderBy(commentList, ['like'], ['desc']))} else {// 最新 => 创建时间降序// lodash函数库,desc降序排序setCommentList(_.orderBy(commentList, ['ctime'], ['desc']))}}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 */}{tabs.map(item =><spankey={item.type}className={`nav-item ${type === item.type ? 'active' : ''}`}onClick = {() => handleTabChange(item.type)}>{item.text}</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={ljAvatar} 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 className="reply-item" key={item.rpid}>{/* 头像 */}<div className="root-reply-avatar"><div className="bili-avatar"><imgclassName="bili-avatar-img"alt=""src = {item.user.avatar}/></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>{/* 显示条件: user.id === item.user.id */}{user.uid === item.user.uid &&<span className="delete-btn" onClick={() => handleDel(item.rpid)}>删除</span>}</div></div></div></div>) )}<div className="reply-item">{/* 头像 */}<div className="root-reply-avatar"><div className="bili-avatar"><imgclassName="bili-avatar-img"alt=""/></div></div></div></div></div></div>)
}export default App
//App.scss.app {width: 80%;margin: 50px auto;
}.reply-navigation {margin-bottom: 22px;.nav-bar {display: flex;align-items: center;margin: 0;padding: 0;list-style: none;.nav-title {display: flex;align-items: center;width: 114px;font-size: 20px;.nav-title-text {color: #18191c;font-weight: 500;}.total-reply {margin: 0 36px 0 6px;color: #9499a0;font-weight: normal;font-size: 13px;}}.nav-sort {display: flex;align-items: center;color: #9499a0;font-size: 13px;.nav-item {cursor: pointer;&:hover {color: #00aeec;}&:last-child::after {display: none;}&::after {content: ' ';display: inline-block;height: 10px;width: 1px;margin: -1px 12px;background-color: #9499a0;}}.nav-item.active {color: #18191c;}}}
}.reply-wrap {position: relative;
}
.box-normal {display: flex;transition: 0.2s;.reply-box-avatar {display: flex;align-items: center;justify-content: center;width: 80px;height: 50px;}.reply-box-wrap {display: flex;position: relative;flex: 1;.reply-box-textarea {width: 100%;height: 50px;padding: 5px 10px;box-sizing: border-box;color: #181931;font-family: inherit;line-height: 38px;background-color: #f1f2f3;border: 1px solid #f1f2f3;border-radius: 6px;outline: none;resize: none;transition: 0.2s;&::placeholder {color: #9499a0;font-size: 12px;}&:focus {height: 60px;background-color: #fff;border-color: #c9ccd0;}}}.reply-box-send {position: relative;display: flex;flex-basis: 86px;align-items: center;justify-content: center;margin-left: 10px;border-radius: 4px;cursor: pointer;transition: 0.2s;& .send-text {position: absolute;z-index: 1;color: #fff;font-size: 16px;}&::after {position: absolute;width: 100%;height: 100%;background-color: #00aeec;border-radius: 4px;opacity: 0.5;content: '';}&:hover::after {opacity: 1;}}
}
.bili-avatar {position: relative;display: block;width: 48px;height: 48px;margin: 0;padding: 0;border-radius: 50%;
}
.bili-avatar-img {position: absolute;top: 50%;left: 50%;display: block;width: 48px;height: 48px;object-fit: cover;border: none;border-radius: 50%;image-rendering: -webkit-optimize-contrast;transform: translate(-50%, -50%);
}// 评论列表
.reply-list {margin-top: 14px;
}
.reply-item {padding: 22px 0 0 80px;.root-reply-avatar {position: absolute;left: 0;display: flex;justify-content: center;width: 80px;cursor: pointer;}.content-wrap {position: relative;flex: 1;&::after {content: ' ';display: block;height: 1px;width: 100%;margin-top: 14px;background-color: #e3e5e7;}.user-info {display: flex;align-items: center;margin-bottom: 4px;.user-name {height: 30px;margin-right: 5px;color: #61666d;font-size: 13px;line-height: 30px;cursor: pointer;}}.root-reply {position: relative;padding: 2px 0;color: #181931;font-size: 15px;line-height: 24px;.reply-info {position: relative;display: flex;align-items: center;margin-top: 2px;color: #9499a0;font-size: 13px;.reply-time {width: 86px;margin-right: 20px;}.reply-like {display: flex;align-items: center;margin-right: 19px;.like-icon {width: 14px;height: 14px;margin-right: 5px;color: #9499a0;background-position: -153px -25px;&:hover {background-position: -218px -25px;}}.like-icon.liked {background-position: -154px -89px;}}.reply-dislike {display: flex;align-items: center;margin-right: 19px;.dislike-icon {width: 16px;height: 16px;background-position: -153px -153px;&:hover {background-position: -217px -153px;}}.dislike-icon.disliked {background-position: -154px -217px;}}.delete-btn {cursor: pointer;&:hover {color: #00aeec;}}}}}
}.reply-none {height: 64px;margin-bottom: 80px;color: #99a2aa;font-size: 13px;line-height: 64px;text-align: center;
}
// index.jsimport { createRoot } from 'react-dom/client'
import App from './App'const root = createRoot(document.querySelector('#root'))root.render(<App />)

相关文章:

React:B站评论demo,实现列表渲染、删除按钮显示和功能实现、导航栏渲染切换及高亮显示、评论区的排序

功能要求&#xff1a; 1、渲染评论列表 2、删除评论功能&#xff1a;只显示自己评论的删除按钮&#xff1b;点击删除按钮&#xff0c;删除当前评论&#xff0c;列表中不再显示。 3、渲染导航Tab&#xff08;最新 | 最热&#xff09;和其 高亮实现 4、评论排序功能实现&…...

支持IPD项目管理的9大系统,哪款工具能有效提高项目控制能力

本文介绍了以下9大系统: 1.Worktile&#xff1b; 2. 腾讯敏捷开发平台&#xff08;TAPD&#xff09;&#xff1b; 3. 简道云&#xff08;Jiandaoyun&#xff09;&#xff1b; 4. 蓝鲸智云&#xff08;BlueWhale&#xff09;&#xff1b; 5. 轻流&#xff08;Qingflow&#xff0…...

4070Super安装GPU版本pytorch记录

一些啐啐念。 安装LLaMA-Factory时遇到pytorch安装成CPU版本。网上找了一圈攻略&#xff0c;都是下载龟速。挂梯子也一样。最后在尝试用pytorch官网的生成的命令进行安装时&#xff0c;突然奇想&#xff0c;直接把安装日志显示的下载链接复制到浏览器下载&#xff0c;发现可以满…...

SpringBoot 端口配置

在Spring Boot中&#xff0c;配置应用程序的监听端口有多种方式。以下是常见的几种方法&#xff1a; 1. 通过 application.properties 或 application.yml 文件配置 application.properties server.port8081application.yml server:port: 8081如果没有显式配置 server.port…...

Linux网络相关概念和重要知识(1)(网络协议、网络通信)

目录 1.网络协议 &#xff08;1&#xff09;网络的起源 &#xff08;2&#xff09;为什么需要协议 &#xff08;3&#xff09;协议分层及其设计的解耦 &#xff08;4&#xff09;OSI定义的七层网络模型 ①分层及其功能 ②TCP/IP协议 ③传输层协议&#xff08;TCP和UDP&a…...

go前后端开源项目go-admin,本地启动

https://github.com/go-admin-team/go-admin 教程 1.拉取项目 git clone https://github.com/go-admin-team/go-admin.git 2.更新整理依赖 go mod tidy会整理依赖&#xff0c;下载缺少的包&#xff0c;移除不用的&#xff0c;并更新go.sum。 # 更新整理依赖 go mod tidy 3.编…...

爬虫系列之发送请求与响应《一》

一、请求组成 1.1 请求方式&#xff1a;GET和POST请求 GET:从服务器获取&#xff0c;请求参数直接附在URL之后&#xff0c;便于查看和分享&#xff0c;常用于获取数据和查询操作 POST&#xff1a;用于向服务器提交数据&#xff0c;其参数不会显示在URL中&#xff0c;而是包含在…...

【数据挖掘】Matplotlib

Matplotlib 是 Python 最常用的 数据可视化 库之一&#xff0c;在数据挖掘过程中&#xff0c;主要用于 数据探索 (EDA)、趋势分析、模式识别 和 结果展示。 &#x1f4cc; 1. Matplotlib 基础 1.1 安装 & 导入 # 如果未安装 Matplotlib&#xff0c;请先安装 # pip instal…...

AtCoder Beginner Contest 001(A - 積雪深差、B - 視程の通報、C - 風力観測、D - 感雨時刻の整理)题目翻译

由于我发现网上很少有人会发很久之前AtCoder Beginner Contes的题&#xff0c;所以我打算从AtCoder Beginner Contest 001开始写。大约两周一更&#xff0c;需要的可以订阅专栏&#xff0c;感谢支持Thanks♪(&#xff65;ω&#xff65;)&#xff89; →题目讲解 A - 積雪深差 …...

安全测试之五:SQL Server注入漏洞几个实例

示例 1&#xff1a;在 GET 请求中测试 SQL 注入 最简单且有时最有效的情况是针对登录页面进行测试。当登录页面请求用户输入用户名和密码时&#xff0c;攻击者可以尝试输入以下字符串 “ or 11”&#xff08;不包含双引号&#xff09;&#xff1a; https://vulnerable.web.ap…...

如何在Github上面上传本地文件夹

前言 直接在GitHub网址上面上传文件夹是不行的&#xff0c;需要一层一层创建然后上传&#xff0c;而且文件的大小也有限制&#xff0c;使用Git进行上传更加方便和实用 1.下载和安装Git Git - Downloads 傻瓜式安装即可 2.获取密钥对 打开自己的Github&#xff0c;创建SSH密钥&…...

多Agent协作智能系统

多Agent协作智能系统商业计划书 ——基于文心大模型的虚拟世界协作解决方案 第一章 执行摘要 1.1 项目背景 技术驱动:文心大模型4.0工具版的推出标志着AI从“问答”向“行动”的跨越,多Agent协作成为复杂任务自动化的核心范式。市场需求:据Global Market Insights报告,20…...

第J1周:ResNet50算法(Tensorflow版)

&#x1f368; 本文为&#x1f517;365天深度学习训练营 中的学习记录博客&#x1f356; 原作者&#xff1a;K同学啊 目标 具体实现 &#xff08;一&#xff09;环境 语言环境&#xff1a;Python 3.10 编 译 器: PyCharm 框 架: TensorFlow &#xff08;二&#xff09;具体…...

炸裂函数explode

在 Apache Hive 中&#xff0c;"炸裂函数"通常指的是将复杂数据类型&#xff08;如数组或映射&#xff09;拆分成多行的函数。Hive 提供了几个内置函数来实现这种操作&#xff0c;其中最常用的是 explode 函数。 1. explode 函数 explode 函数用于将数组或映射类型…...

计算机视觉(opencv-python)之图像预处理基本操作(待补充)

图像预处理是计算机视觉任务中的关键步骤&#xff0c;它通过对原始图像进行处理&#xff0c;以提高后续图像分析、特征提取和识别的准确性。 示例图片 目录 常见图像处理方法 灰度化处理 法一 法二 说明 切片截取部分图像数据 cv2.cvtColor() 颜色空间转换 cv2.split(…...

数据结构秘籍(四) 堆 (详细包含用途、分类、存储、操作等)

1 引言 什么是堆&#xff1f; 堆是一种满足以下条件的树&#xff1a;&#xff08;树这一篇可以参考我的文章数据结构秘籍&#xff08;三&#xff09;树 &#xff08;含二叉树的分类、存储和定义&#xff09;-CSDN博客&#xff09; 堆中的每一个结点值都大于等于&#xff08…...

前端正则表达式完全指南:从入门到实战

文章目录 第一章&#xff1a;正则表达式基础概念1.1 什么是正则表达式1.2 正则表达式工作原理1.3 基础示例演示 第二章&#xff1a;正则表达式核心语法2.1 元字符大全表2.2 量词系统详解2.3 字符集合与排除 第三章&#xff1a;前端常用正则模式3.1 表单验证类3.1.1 邮箱验证3.1…...

【SRC实战】小游戏漏洞强制挑战

小游戏业务分析: 1、挑战成功加分&#xff0c;失败减分&#xff0c;存在段位机制&#xff0c;段位影响榜单排名 2、随机推荐挑战对象&#xff0c;随着等级升高不再推荐低等级玩家 3、玩家等级需要培养&#xff0c;培养需要道具&#xff0c;道具需要看广告/完成任务/付费 4、…...

细说 Java 集合之 Map

前言&#xff1a;本文基于JDK8 一、HashMap 1.1、hash方法 hash方法是map中的基石&#xff0c;后续很多操作都依赖hash方法&#xff1b; 下面是 jdk 7 中 hash方法&#xff0c;注意hashSeed 这个扰动因子&#xff0c;该值随机&#xff0c;所以同一个 key 每次调用hash方法后…...

【vue-echarts】——05.柱状图

文章目录 一、柱状图基本设置1.实现代码2.结果展示二、柱状图效果实现11.代码实现2.结果展示三、柱状图效果实现21.代码实现2.结果展示一、柱状图基本设置 柱状图:一种图表类型,因为构成是由一根一根类似柱子的数据条组合而成的坐标平面,所以命名为柱状 图。主要是用来反应对…...

LimboAI:Godot 4原生行为树+黑板+状态机AI框架实战指南

1. 这不是又一个“AI插件”&#xff0c;而是Godot 4里真正能跑通行为树黑板状态机闭环的AI开发框架我第一次在Godot 4.2项目里把LimboAI的BTTaskMoveTo节点拖进行为树编辑器、连上BlackboardKey、再绑定到一个带NavigationAgent3D的NPC身上&#xff0c;按下F5运行——那个角色真…...

ARGUS:视觉中心化多模态推理框架,实现像素级可验证Chain-of-Thought

1. 项目概述&#xff1a;这不是又一个“多模态大模型”&#xff0c;而是一次视觉推理范式的重新校准ARGUS这个名字&#xff0c;乍看像某个军事侦察系统代号&#xff0c;其实它精准指向了当前多模态AI领域最棘手的痛点——视觉信息在推理链中长期处于“失语”状态。你肯定见过这…...

ElevenLabs广西话输出突然失真?一文定位3类隐藏错误:声母浊化丢失、入声韵尾截断、连读变调失效

更多请点击&#xff1a; https://intelliparadigm.com 第一章&#xff1a;ElevenLabs广西话语音输出失真现象概览 ElevenLabs 作为当前主流的AI语音合成平台&#xff0c;其多语言支持能力广受开发者青睐。然而&#xff0c;在针对广西话&#xff08;粤语勾漏片与邕浔片混合变体…...

2026浏览器侧信道指纹检测技术研究与防护方案落地

一、引言常规浏览器指纹检测依托页面脚本读取显性设备参数&#xff0c;这类识别方式早已被各类虚拟浏览工具针对性规避。近两年各大互联网平台开始大规模部署侧信道指纹检测体系&#xff0c;跳出表层参数读取的局限&#xff0c;借助硬件运行损耗、指令执行耗时、内存调度特征、…...

JWT权限治理:从无状态凭证到可管控权限单元

1. 这不是又一个“登录后跳转首页”的玩具项目JWT在Java Web权限控制里被讲烂了&#xff0c;但绝大多数人写的所谓“基于JWT的系统”&#xff0c;其实连Token刷新都靠前端定时重登&#xff0c;后端连黑名单都没建&#xff0c;更别提并发登出、设备绑定、权限粒度动态变更这些真…...

美股软件股反弹:AI 重塑软件未来,谁能成为时代赢家?

美股软件股遭遇“集体误杀”去年 10 月底开始&#xff0c;美股软件股经历罕见“集体误杀”。以软件 ETF——IGV 为代表&#xff0c;软件板块从高位显著回撤&#xff0c;跌幅接近 40%。曾经的高质量成长资产软件公司&#xff0c;沦为 AI 浪潮下的“旧世界遗产”。恐慌源于 DeepS…...

国产多模态大模型 vs DALL-E:本土化突围与全球竞技

国产多模态大模型 vs DALL-E&#xff1a;本土化突围与全球竞技 引言 在AIGC浪潮席卷全球的当下&#xff0c;OpenAI的DALL-E系列无疑是图像生成领域的耀眼明星&#xff0c;其惊人的创造力和对自然语言的深刻理解&#xff0c;定义了“文生图”的新高度。然而&#xff0c;当我们聚…...

记一次 .NET 某集群管理软件 内存暴涨分析

一&#xff1a;背景 1. 讲故事 前些天有位朋友微信找到我&#xff0c;说它的程序出现了内存暴涨&#xff0c;自己也没分析出啥&#xff0c;让我看下到底怎么回事&#xff0c;然后让这位朋友抓一个dump&#xff0c;拿它占一卦就行了。 二&#xff1a;内存暴涨分析 1. 为什么会暴…...

图片去水印怎么做?2026年最全图片去水印工具推荐与方法盘点

在日常工作和生活中&#xff0c;我们常常会遇到带有水印的图片——无论是社交平台的截图、素材库的图片&#xff0c;还是从各类网站下载的资源。水印虽然保护了原作者的权益&#xff0c;但有时也会影响我们对内容本身的使用。那么&#xff0c;图片去水印有哪些实用方法&#xf…...

ElevenLabs江苏话语音模型训练全链路拆解:从200小时带标注吴语语料清洗,到MOS得分达4.13的关键超参组合

更多请点击&#xff1a; https://intelliparadigm.com 第一章&#xff1a;ElevenLabs江苏话语音模型训练全链路拆解&#xff1a;从200小时带标注吴语语料清洗&#xff0c;到MOS得分达4.13的关键超参组合 语料清洗与方言对齐策略 针对原始200小时江苏话&#xff08;含苏州、无…...