基于React实现B站评论区

        今天继续来学习一下React,使用React实现B站评论区,如下图:

        在使用React开发类似B站评论区的功能时,我们需要考虑以下几个关键点来构建一个基本的评论系统:

1. 设计组件结构

首先,设计组件结构是关键。至少需要以下几种组件:

  • CommentList: 负责展示评论列表。
  • Comment: 单个评论项的展示,包括用户名、评论内容、时间戳等。
  • CommentContent: 用户输入评论的内容,包括文本输入框和提交按钮。
  • User: 当前的登录的用户
  • TabList: 评论排序的导航类型

2. 管理状态

        使用React的状态管理功能(如useState或useReducer)来处理评论数据和表单输入状态。例如,可以创建一个状态来存储所有的评论数据,以及一个状态来管理评论表单的输入值。

3. 发送和获取评论

当然,本次实现不考虑连接后端,只利用假的数据来实现B站评论区的按照热度、事件排序展示、删除评论、发布评论。如果需要连接后端可以考虑下面你的操作:

获取评论:  如果评论数据来自后端API,可以使用fetch或第三方库如axios来获取数据,并在组件挂载时或根据需要触发请求。
发送评论: 当用户提交评论时,捕获表单数据并发送POST请求到后端API,成功后通常会刷新评论列表以显示新评论。
删除评论:当用户删除评论的时候,捕获评论Id并发送DELETE请求到后端API,后端根据ID删除该条评论。

4. 代码实现

import './App.scss'
import {useState} from "react";
import avatar1 from './images/1.png';
import avatar2 from './images/2.png';
import stukk from './images/lyy.jpg';/*** 评论列表的渲染和操作** 1. 根据状态渲染评论列表* 2. 删除评论* 3. 发布评论*/// 评论列表数据
const defaultList = [{// 评论idrpid: 3,// 用户信息user: {uid: '13258165',avatar: avatar1,uname: '周杰伦',},// 评论内容content: '哎哟,不错哦',// 评论时间ctime: '10-18 08:15',like: 98,},{rpid: 2,user: {uid: '36080105',avatar: avatar2,uname: '许嵩',},content: '我寻你千百度 日出到迟暮',ctime: '11-13 11:29',like: 88,},{rpid: 1,user: {uid: '30009257',avatar: stukk,uname: 'stu_kk',},content: '关注stu_kk',ctime: '10-19 09:00',like: 66,},
]
// 当前登录用户信息
const user = {// 用户iduid: '30009257',// 用户头像avatar: stukk,// 用户昵称uname: 'stu_kk',
}/*** 导航 Tab 的渲染和操作** 1. 渲染导航 Tab 和高亮* 2. 评论列表排序*  最热 => 喜欢数量降序*  最新 => 创建时间降序*/// 导航 Tab 数组
const tabs = [{type: 'hot', text: '最热', isActive: true},{type: 'time', text: '最新', isActive: false},
]const App = () => {const [commentList, setCommentList] = useState(defaultList); // 评论列表const [tabList, setTabList] = useState(tabs); // 导航 Tab 数组const [commentContent, setCommentContent] = useState(''); // 评论内容const changeTabList = (id) => { //改变导航Tabconst newTabList = tabList.map((item, index) => {if (index === id) {item.isActive = true;} else {item.isActive = false;}return item;});return newTabList;}const clickTab = (id) => { // 点击导航Tabconst newCommentList = id === 0 ? commentList.sort((a, b) => b.like - a.like) : commentList.sort((a, b) => (b.ctime > a.ctime ? 1 : -1));console.log(newCommentList)setCommentList(newCommentList);setTabList(changeTabList(id));}const sendComment = () => { //发布评论console.log(111)if (commentContent.trim() === '') {alert('评论内容不能为空');return;}const newCommentList = [{rpid: commentList.length + 1,user: user,content: commentContent,ctime: '12-19 09:00',like: 0,},...commentList,];setCommentList(newCommentList);setCommentContent('');}const deleteCommentById = (id) => { //根据Id删除自己的评论setCommentList(commentList.filter((item) => item.rpid !== id))}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 */}{tabList.map((item,index) => (<span onClick={()=>clickTab(index)} className={item.isActive ? 'nav-item active' : 'nav-item'}  key={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={user.avatar} alt="用户头像"/></div></div><div className="reply-box-wrap">{/* 评论框 */}<textareaclassName="reply-box-textarea"placeholder="发一条友善的评论"value={commentContent}onChange={(e) => setCommentContent(e.target.value)}/>{/* 发布按钮 */}<div className="reply-box-send" onClick={sendComment}><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>{/*根据用户与当前用户对比,设置是否有权限删除*/}{item.user.uid === user.uid && <span className="delete-btn" onClick={() => deleteCommentById(item.rpid)}>删除</span> }</div></div></div></div>))}</div></div></div>)
}export default App

5. 实现效果

6. 代码解释

        上面React代码实现了一个基础的评论区功能,包含评论列表的渲染、导航Tab切换(用于排序)、发布评论、以及删除自己的评论功能。下面是对代码的详细解析:
1. 数据初始化
        评论列表数据 (defaultList): 定义了初始的评论数据数组,每个评论对象包含了评论ID (rpid)、用户信息 (user)、评论内容 (content)、评论时间 (ctime) 和点赞数 (like)。
当前登录用户信息 (user): 包含用户ID、头像和用户名,用于识别和执行删除操作。
2. 状态管理

  • 使用 useState Hook 来管理组件状态:
  • commentList: 当前的评论列表。
  • tabList: 导航Tab的状态,包括类型、文本和是否激活。
  • commentContent: 用户在评论框中输入的内容。

3. 导航Tab功能

  • tabs: 定义了两个导航Tab选项:“最热”和“最新”,每个Tab都有一个类型 (type)、文本 (text) 和激活状态 (isActive)。
  • changeTabList: 函数用来改变Tab的激活状态。
  • clickTab: 处理Tab点击事件,根据选择的Tab类型对评论列表进行排序,并更新Tab的激活状态。

4. 发布评论
        sendComment: 用户点击“发布”按钮时调用此函数,检查评论内容是否为空,然后将新评论追加到评论列表的开头,并清空输入框。
5. 删除评论
        deleteCommentById: 根据评论ID从评论列表中删除对应的评论,仅允许用户删除自己发布的评论。
6. UI渲染

  • 导航Tab (reply-navigation): 渲染导航Tab,根据tabList的状态来决定哪个Tab被高亮显示。
  • 评论输入框和发布按钮: 用户可以在此输入评论内容并发布。
  • 评论列表 (reply-list): 根据commentList渲染评论项,每个评论项包含用户头像、用户名、评论内容、评论时间和删除按钮(如果当前登录用户是评论作者)。

7. 总结

        文章使用React构建了一个仿照B站基本的前端评论系统,实现了动态加载、排序、添加和删除评论的基本功能。通过React的状态管理和事件处理机制,实现了交互式的用户体验。但是在实际应用中,还需考虑与后端接口的交互、错误处理、分页加载、以及更复杂的用户交互逻辑。

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

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

相关文章

Unity Animation--动画剪辑

Unity Animation--动画剪辑 动画剪辑 动画剪辑是Unity动画系统的核心元素之一。Unity支持从外部来源导入动画&#xff0c;并提供创建动画剪辑的能力使用“动画”窗口在编辑器中从头开始。 外部来源的动画 从外部来源导入的动画剪辑可能包括&#xff1a; 人形动画 运动捕捉…

Python中关于子类约束的开发规范

Python中关于子类约束的开发规范 我们知道&#xff0c;在java和C#中有一种接口的类型&#xff0c;用来约束实现该接口的类&#xff0c;必须要定义接口中指定的方法 而在python中&#xff0c;我们可以基于父类子类异常来仿照着实现这个功能 class Base:def func():raise NotI…

css---浮动知识点精炼汇总

前言 欢迎来到我的博客 个人主页:北岭敲键盘的荒漠猫-CSDN博客 浮动简单理解与介绍 这是我们普通的页面标签效果。 每个标签从上到下依次排列。 浮动顾名思义就是让这个标签飞翔起来。 他飞起来后&#xff0c;后面的标签来到他的位置上。 而浮动的标签就会显示在标签的上面。…

设计模式之MVC模式

在编程江湖闯荡多年&#xff0c;我手中打磨过的设计模式多如繁星&#xff0c;但论及经典与实用&#xff0c; MVC&#xff08;Model-View-Controller&#xff09;模式 绝对是个中翘楚&#xff01;它不仅是Web应用的骨架&#xff0c;更是软件架构的智慧结晶。今天&#xff0c;咱们…

头歌:Spark案例剖析 - 谷歌网页排名引擎PageRank实战

第1关:海量数据导入:SparkSQL大数据导入处理 任务描述 工欲善其事必先利其器,大数据分析中最重要的是熟练掌握数据导入工具的使用方法。Spark SQL是Spark自带的数据库,本关你将应用Spark SQL的数据导入工具实现文本数据的导入。其中,graphx-wiki-vertices.txt文件中含有网…

010_redhat安装zookeeper

目录 1.环境准备2.下载上传zookeeper安装包1)[官网下载zookeeper-3.6.4安装包](https://archive.apache.org/dist/zookeeper/zookeeper-3.6.4/apache-zookeeper-3.6.4-bin.tar.gz)2)创建soft文件夹 3.解压4.配置启动1、配置zoo.cfg2、启动zookeeper 小结 1.环境准备 准备一台l…

如何创建一个 Django 应用并连接到数据库

简介 Django 是一个用 Python 编写的免费开源的 Web 框架。这个工具支持可扩展性、可重用性和快速开发。 在本教程中&#xff0c;您将学习如何为一个博客网站建立与 MySQL 数据库的初始基础。这将涉及使用 django-admin 创建博客 Web 应用程序的骨架结构&#xff0c;创建 MyS…

LeetCode-网络延迟时间(Dijkstra算法)

每日一题 今天刷到一道有关的图的题&#xff0c;需要求单源最短路径&#xff0c;因此使用Dijkstra算法。 题目要求 有 n 个网络节点&#xff0c;标记为 1 到 n。 给你一个列表 times&#xff0c;表示信号经过 有向 边的传递时间。 times[i] (ui, vi, wi)&#xff0c;其中 …

wordpress外贸独立站建站10要10不要

创建一个成功的WordPress外贸独立站需要注意很多因素。以下是zhanyes根据多年建站经验总结的wordpress外贸独立站建站的10个建议和10个避免的事项&#xff0c;以帮助您建立一个高质量的外贸网站&#xff1a; 10个要&#xff1a; 1. 要选择合适的域名&#xff1a;确保您的域名…

element-ui的bug记录

1.先隐藏元素再显示元素时&#xff0c;导致校验不生效的做法 <el-form-itemlabel"时间长度"prop"timeLength"v-show"form.majorFlag":rules"[{ required: form.majorFlag ? true : false, message: 时间长度不能为空, trigger: blur }…

pyppeteer 执行js函数调用ajax post传入参数并获取返回值

在Pyppeteer中&#xff0c;你可以使用page.evaluate()方法来执行JavaScript函数&#xff0c;并且可以传递参数给这个函数。如果你需要执行一个调用AJAX POST请求的函数并且传入参数&#xff0c;同时需要获取返回值&#xff0c;可以使用以下方法&#xff1a; import asyncio fr…

Mybatis-Plus学习:快速入门、核心功能、扩展功能、插件功能

文章目录 MybatisPlus快速入门快速开始常见注解常见配置 核心功能条件构造器&#xff08;Wrapper&#xff09;自定义SQLService接口基本用法基础业务接口复杂业务接口Lamda查询Lamda更新批量新增 扩展功能代码生成代码生成器快速开发插件 静态工具逻辑删除枚举处理器JSON处理器…

Java实现裁剪PDF

目录 安装Java PDF库 Java裁剪PDF页面 Java裁剪PDF页面并将结果保存为图片、HTML、Excel等格式 裁剪PDF页面是一项常见的任务&#xff0c;它可以用来调整文档的尺寸和去除不需要的边距或白边。通过裁剪页面&#xff0c;你可以优化文档的布局和展示效果&#xff0c;使其更符合…

万界星空科技商业开源MES+项目合作+商业开源低代码平台

今天我想和大家分享的是一套商业开源的 MES制造执行管理系统带源码。对于制造业而言&#xff0c;MES 是一个至关重要的系统&#xff0c;它可以帮助企业提高生产效率、优化资源利用、提高产品质量&#xff0c;从而增强市场竞争力。 什么是 MES&#xff1f; MES 是指通过计算机技…

不通过分组注解计数:Django查询集的高级用法

Django的查询集提供了各种高级用法&#xff0c;可以在不使用分组注解的情况下进行计数。下面是一些常用的高级用法示例&#xff1a; count()方法&#xff1a; 最简单的方法是使用count()方法来计算查询集中的对象数量。例如&#xff1a; num_objects MyModel.objects.count()f…

# notepad++ 编辑器英文版,如何打开自动换行

notepad 编辑器英文版&#xff0c;如何打开自动换行 在Notepad中&#xff0c;如果你想要开启自动换行功能&#xff0c;可以按照以下步骤操作&#xff1a; 1、打开 Notepad 编辑器。 1.1. 依次点击菜单栏中的【视图】&#xff0c;英文版对应【View】。1.2. 在【视图】下拉菜单…

商务谈判技巧与口才书籍有哪些类型

商务谈判技巧与口才书籍有哪些类型&#xff08;3篇&#xff09; 商务谈判技巧与口才书籍的类型丰富多样&#xff0c;以下从三个角度进行介绍&#xff1a; **篇&#xff1a;基础理论与策略类书籍 这类书籍通常深入剖析谈判的本质&#xff0c;系统介绍谈判的原理、技巧和策略。…

QProcess 使用实例

QProcess运行一个命令行&#xff0c;比如ipconfig示例cpp主要的代码如下所示&#xff1a; QStringList m_Arguments; m_Arguments << "/c" << "ipconfig"; QString m_Command("cmd.exe"); QString m_Input; run(); / QStr…

量子城域网建设设备系列(二):量子密钥管系统(KMS)

在上文介绍光量子交换机的文章中我们提到&#xff0c;量子保密通信网络的通道切换是由量子密钥管理系统&#xff08;Key Management System&#xff0c;KMS&#xff09;给光量子交换机下发信道切换指令&#xff0c;实现整个网络中任意两对量子密钥分发终端的量子信道互联互通&a…

WPF之ToolTip提示

ToolTip控件在WPF担任着提示信息的位置&#xff0c;当鼠标悬停在某个标签上时ToolTip中的信息会显示&#xff0c;使用时将ToolTip放在某个标签内部或者设置某个标签的ToolTip属性。 使用方法1 <TextBox Width"300"Height"40"HorizontalAlignment"…