【react案例】实现评论列表

embedded/2024/10/20 19:16:05/

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.ppmy.cn/embedded/118225.html

相关文章

Translation Consistent Semi-supervised Segmentation for 3D Medical Images 阅读

code: yyliu01/TraCoCo: [TMI24] Translation Consistent Semi-supervised Segmentation for 3D Medical Images (github.com) paper:Translation Consistent Semi-supervised Segmentation for 3D Medical Images (arxiv.org) Abstract 三维医学图像分割方法已经取得了成功…

数字游戏C++

题目: 题目就是让你输入一个长度为88的0101串&#xff0c;让你求出中间1有几个。 wo一看到这题&#xff0c;立马想到暴力求解&#xff1a;循环八遍&#xff0c;每次输入一个char&#xff0c;减掉四十八加一起&#xff0c;输出&#xff0c; 细细一想&#xff1a;诶&#xff0c;…

【Java】网络编程-地址管理-IP协议后序-NAT机制-以太网MAC机制

&#x1f308;个人主页&#xff1a;努力学编程’ ⛅个人推荐&#xff1a; c语言从初阶到进阶 JavaEE详解 数据结构 ⚡学好数据结构&#xff0c;刷题刻不容缓&#xff1a;点击一起刷题 &#x1f319;心灵鸡汤&#xff1a;总有人要赢&#xff0c;为什么不能是我呢 &#x1f434…

每天一个数据分析题(四百七十六)- 线性回归建模

关于线性回归建模&#xff0c;线性回归分析中&#xff0c;回归方程的检验是&#xff1f; A. t检验 B. 卡方检验 C. F检验 D. 正态检验 数据分析认证考试介绍&#xff1a;点击进入 题目来源于CDA模拟题库 点击此处获取答案 数据分析专项练习题库 内容涵盖Python&#xf…

发票OFD格式转换成PDF

引入依赖&#xff0c;低版本的报错&#xff0c;2.0.2能够实现转换 <dependency><groupId>org.ofdrw</groupId><artifactId>ofdrw-converter</artifactId><version>2.0.2</version><exclusions><exclusion><groupId&g…

线性代数复习笔记

∣ A ∣ ∑ j 1 n a i j A i j ( i 1 , 2 , . . . , n ) ∑ i 1 n a i j A i j ( j 1 , 2 , . . . , n ) ; A i j ( − 1 ) i j M i j . |A|\sum_{j1}^na_{ij}A_{ij}\ (i1,2,...,n)\sum_{i1}^na_{ij}A_{ij}\ (j1,2,...,n);\ A_ij(-1)^{ij}M_{ij}. ∣A∣∑j1n​aij​Aij…

Spring Cloud Alibaba-(6)Spring Cloud Gateway【网关】

Spring Cloud Alibaba-&#xff08;1&#xff09;搭建项目环境 Spring Cloud Alibaba-&#xff08;2&#xff09;Nacos【服务注册与发现、配置管理】 Spring Cloud Alibaba-&#xff08;3&#xff09;OpenFeign【服务调用】 Spring Cloud Alibaba-&#xff08;4&#xff09;Sen…

16.3 k8s容器cpu内存告警指标与资源request和limit

本节重点介绍 : Guaranteed的pod Qos最高在生产环境中&#xff0c;如何设置 Kubernetes 的 Limit 和 Request 对于优化应用程序和集群性能至关重要。对于 CPU&#xff0c;如果 pod 中服务使用 CPU 超过设置的limits&#xff0c;pod 不会被 kill 掉但会被限制。如果没有设置 li…