基于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; 人形动画 运动捕捉…

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

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

设计模式之MVC模式

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

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

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

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

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

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

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

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

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

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

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

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

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

【跟马少平老师学AI】-【神经网络是怎么实现的】(九)长短期记忆网络

一句话归纳&#xff1a; 1&#xff09;RNN也会存在梯度消失的问题。 2&#xff09;同一句话&#xff0c;对于不同的任务&#xff0c;句中不同的词起的作用也不一样。 3&#xff09;LSTM&#xff08;长短期记忆&#xff09;子网络&#xff1a; 门&#xff0c;让输入经过运算&…

与Apollo共创生态:探索自动驾驶的未来蓝图

目录 引言Apollo开放平台Apollo开放平台企业生态计划Apollo X 企业自动驾驶解决方案&#xff1a;加速企业场景应用落地Apollo开放平台携手伙伴共创生态生态共创会员权益 个人心得与展望技术的多元化应用数据驱动的智能化安全与可靠性的重视 结语 引言 就在2024年4月19日&#x…

SpringBoot的ProblemDetails

1.RFC 7807 之前的项目如果出现异常&#xff0c;默认跳转到error页面。或者是抛出500 异常。 但是对于前后端分离的项目&#xff0c;Java程序员不负责页面跳转&#xff0c;只需要 把错误信息交给前端程序员处理即可。而RFC 7807规范就是将异常 信息转为JSON格式的数据。这个…

导数之光:探寻机器学习中的微变奥秘

在当今这个数据驱动的时代&#xff0c;机器学习以其强大的学习和预测能力&#xff0c;成为了推动科技进步的重要力量。而在机器学习的背后&#xff0c;数学原理&#xff0c;尤其是导数的应用&#xff0c;为其提供了坚实的理论支撑。本文将详细探讨导数在机器学习中的体现&#…

如何使用 GPT API 从 PDF 出版物导出研究图表?

原文地址&#xff1a;how-to-use-gpt-api-to-export-a-research-graph-from-pdf-publications 揭示内部结构——提取研究实体和关系 2024 年 2 月 6 日 介绍 研究图是研究对象的结构化表示&#xff0c;它捕获有关实体的信息以及研究人员、组织、出版物、资助和研究数据之间的关…

IDEA 创建Servlet-HelloWorldServlet

servlet 1.创建空项目2.配置web项目3.配置Tomcat4.加载Tomcat包5.创建HelloWorldServlet类6.配置web.xml7.运行get与post请求 1.创建空项目 2.配置web项目 3.配置Tomcat 4.加载Tomcat包 5.创建HelloWorldServlet类 public class controller extends HttpServlet {Override//get…

【Mellanox命令之】如何查看系统MFT版本是否与OFED和FW匹配?(mst version、rpm -qa|grep mft)

0. 背景 如果出现升级了OFED&#xff0c;以及FW、lib等&#xff0c;但是在Debug中遇到异常。可能与mft版本不匹配有关。 那么如何获取mft与OFED、FW之间的匹配关系呢&#xff1f; 1. 查看MFT版本 mft因为不是一个命令&#xff0c;而是4类工具的集合&#xff08;参考兄弟篇&a…

DRF版本组件源码分析

DRF版本组件源码分析 在restful规范中要去&#xff0c;后端的API中需要体现版本。 3.6.1 GET参数传递版本 from rest_framework.versioning import QueryParameterVersioning单视图应用 多视图应用 # settings.pyREST_FRAMEWORK {"VERSION_PARAM": "versi…

图像处理1,灰度,data,for循环批处理图片,图片属性查看,图片单通道查看,椒盐噪声的生成,滤波处理,图像分割

图像处理1 灰度处理data库的使用for循环批处理图像对图像属性的查看图片类型图片尺寸图片宽度图像高度通道数总像素个数最大像素值最小像素值&#xff0c;像素平均值图像点像素值 for循环分别显示图像rgb通道椒盐噪声的生成中值滤波处理高斯模糊处理图像切割 灰度处理 from sk…

SpringCloudAlibaba:3.1dubbo

dubbo 概述 简介 Apache Dubbo 是一款 RPC 服务开发框架&#xff0c;用于解决微服务架构下的服务治理与通信问题 官方提供了 Java、Golang、Rust 等多语言 SDK 实现 Dubbo的开源故事 最早在2008年&#xff0c;阿里巴巴就将Dubbo捐献到开源社区&#xff0c;它很快成为了国内开源…

面试:Mybatis(MyBatis执行流程、延迟加载、MyBatis的缓存)

目录 一、MyBatis执行流程 二、MyBatis是否支持延迟加载&#xff1f; 1、什么是延迟加载&#xff1f; 2、延迟加载的原理 三、MyBatis的缓存 1、一级缓存 2、二级缓存 3、注意事项 一、MyBatis执行流程 读取MyBatis配置文件: mybatis-config.xml加载运行环境和映射文件构…