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

【综合案例】使用React编写B站评论案例

一、效果展示

默认效果,一开始默认按照最热进行排序
发布了一条评论
按照最新进行排序
按照最新进行排序

二、效果说明

页面上默认有3条评论,且一开始进入页面的时候是按照点赞数量进行倒序排列展示,可以点击【最热 、最新】进行排序的切换。

在文本框中输入要评论的文本,然后点击【发布】按钮,即可将评论添加到下方的评论列表当中进行展示;如果没有输入任何文本的时候直接点击【发布】按钮会弹出提示对话框。

点击删除按钮可以将对应的评论从评论列表中移除。

三、涉及知识点

3.1 useState

3.1.1 基础使用

useState 是一个 React Hook(函数),它允许我们向组件添加一个状态变量, 从而控制影响组件的渲染结果。

🚩 语法:

const [state, setState] = useState(initialState)
  1. useState是一个函数,返回值是一个数组 
  2. 数组中的第一个参数是状态变量;第二个参数是set函数,用来修改状态变量
  3. useState的参数将作为state的初始值

🚩 本质:

和普通JS变量不同的是,状态变量一旦发生变化组件的视图UI也会跟着变化(数据驱动视图)。

注意事项:

  • useState 是一个 Hook,因此你只能在 组件的顶层 或自己的 Hook 中调用它。你不能在循环或条件语句中调用它。如果你需要这样做,请提取一个新组件并将状态移入其中。
  • 在严格模式中,React 将 两次调用初始化函数,以 帮你找到意外的不纯性。这只是开发时的行为,不影响生产。如果你的初始化函数是纯函数(本该是这样),就不应影响该行为。其中一个调用的结果将被忽略。
3.1.2 修改状态的规则

🚩 状态不可变

在React中,状态被认为是只读的,我们应该始终 替换它而不是修改它, 直接修改状态不能引发视图更新。

🚩 修改对象状态

规则:对于对象类型的状态变量,应该始终传给set方法一个 全新的对象 来进行修改。

3.2  classnames优化类名控制

classnames是一个简单的JS库,可以非常方便的 通过条件动态控制class类名的显示。

 

现在的问题:字符串的拼接方式不够直观,也容易出错。
3.3 受控表单绑定

 概念:使用React组件的状态(useState)控制表单的状态。

 1. 准备一个React状态值

const [value, setValue] = useState('')
2. 通过value属性绑定状态,通过onChange属性绑定状态同步的函数
// 通过value属性绑定react状态
// 绑定onChange事件,通过事件参数e拿到输入框最新的值,反向修改到react状态
<inputtype="text"value={value}onChange={(e) => setValue(e.target.value)}/>
3.4  获取DOM

在React组件中获取 / 操作DOM,需要使用useRef React Hook钩子函数,分为两步:

1. 使用useRef创建 ref 对象,并与 JSX 绑定

2. 在DOM可用时,通过 inputRef.current 拿到 DOM 对象

四、代码实现

4.1 逻辑渲染层

import { useRef, useState } from "react";
import './App.scss'
import avatar from './image/bozai.png'
import dayjs from 'dayjs'
import { v4 as uuidV4 } from 'uuid'
import _ from 'lodash'
import classNames from 'classnames'
function App() {// 当前登录用户信息const user = {// 用户iduid: '30009257',// 用户头像avatar,// 用户昵称uname: '嘟嘟嘟',}// 评论列表数据const defaultList = [{// 评论idrpid: 3,// 用户信息user: {uid: '13258165',avatar: require('./image/panda.jpg'),uname: '周杰伦',},// 评论内容content: '哎哟,不错哦',// 评论时间ctime: '10-18 08:15',like: 88,},{rpid: 2,user: {uid: '36080105',avatar: require('./image/panda.jpg'),uname: '许嵩',},content: '我寻你千百度 日出到迟暮',ctime: '11-13 11:29',like: 88,},{rpid: 1,user: {uid: '30009257',avatar,uname: '黑马前端',},content: '学前端就来黑马',ctime: '10-19 09:00',like: 66,},]// 导航 Tab 数组const tabs = [{ type: 'hot', text: '最热' },{ type: 'time', text: '最新' },]// 最初的时候先按照最热进行倒叙排列const [remarkList, setRemark] = useState(_.orderBy(defaultList, 'hot', 'desc'))const [content, setContent] = useState('')const inputRef = useRef(null)// 发布评论function handleSubmit() {// 阻止提交空数据if (!content) return alert('请输入评论内容')setRemark([{rpid: uuidV4(),//随机iduser,content,ctime: dayjs(new Date()).format('MM-DD HH:mm'),like: 0,},...remarkList])setContent('')//清空输入框中的内容inputRef.current?.focus()//重新聚焦}// 删除评论function handleDel(item) {setRemark(remarkList.filter(v => v.rpid !== item.rpid))}const [type, setType] = useState('hot')/*** tab切换*  1.点击谁就把谁的type记录下来*  2.通过记录的type和每一项遍历时的type做匹配,控制激活类名的显示*/function handleTabChange(type) {setType(type)if (type === 'time') {// 按照时间倒序setRemark(_.orderBy(remarkList, 'ctime', 'desc'))} else {// 按照点赞数倒序setRemark(_.orderBy(remarkList, 'like', 'desc'))}}return (<div className="App"><div className="top"><div className="left"><span className="l-title">评论</span><span>{remarkList.length}</span></div><div className="right">{/* 高亮类名 */}{/* classnames优化类名控制classnames是一个简单的JS库,可以非常方便的通过条件动态控制class类型的显示*/}{tabs.map((item) => {return (<spanclassName={classNames('nav-item', { active: type === item.type })}key={item.type}onClick={() => handleTabChange(item.type)}>{item.text}</span>)})}</div></div><div className="push"><img className="avatar" src={user.avatar} /><textarea className="textarea" placeholder="发一条友善的评论" ref={inputRef} value={content} onChange={(e) => setContent(e.target.value)}></textarea><button className="pushBtn" onClick={handleSubmit}>发布</button></div><div className="main">{/* 评论项 */}{remarkList.map((item) => {return (<div className="m-item" key={item.rpid}><img className="avatar" src={item.user.avatar} /><div className="mi-right"><div>{item.user.uname}</div><div className="text">{item.content}</div><div ><span>{item.ctime}</span><span className="like">点赞数:{item.like}</span><span onClick={() => handleDel(item)}>删除</span></div></div></div>)})}</div></div>);
}export default App;

4.2 样式层

.App{margin: 10px;
}
.top{margin-bottom: 20px;display: flex;align-items: baseline;font-size: 15px;color: #999;
.left{margin-right: 50px;
.l-title{font-size: 20px;font-weight: 700;color: #000;margin-right: 5px;
}
}
.right{display: flex;flex-direction: row;align-items: center;.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: #000;}
}
}
.push{margin-bottom: 20px;display: flex;
.textarea{margin: 0 10px;padding: 10px;flex: 1;min-height: 30px;max-height: 100px;border-radius: 10px;border: none;outline: none;background-color: #ebebeb;
}
.pushBtn{width: 100px;height: 50px;font-size: 16px;color: #fff;border: none;border-radius: 5px;background-color: rgba(0,174,236,0.5);&:hover{background-color: rgba(0,174,236);}
}
}
.avatar{width: 40px;height: 40px;border-radius: 50%;
}.m-item{display: flex;margin-bottom: 10px;
.mi-right{padding-bottom: 10px;margin-left: 10px;flex: 1;font-size: 14px;color: #999;border-bottom: 1px solid #e4e3e3;
}
.text{margin: 10px 0;color: #000;
}
.like{margin: 0 20px;
}
}

相关文章:

【综合案例】使用React编写B站评论案例

一、效果展示 默认效果&#xff0c;一开始默认按照最热进行排序 发布了一条评论 按照最新进行排序 按照最新进行排序 二、效果说明 页面上默认有3条评论&#xff0c;且一开始进入页面的时候是按照点赞数量进行倒序排列展示&#xff0c;可以点击【最热 、最新】进行排序的切换。…...

【AIGC】腾讯云语音识别(ASR)服务在Spring Boot项目中的集成与实践

腾讯云语音识别&#xff08;ASR&#xff09;服务在Spring Boot项目中的集成与实践 引言 在现代软件开发中&#xff0c;语音识别技术的应用越来越广泛&#xff0c;从智能助手到自动客服系统&#xff0c;语音识别技术都在发挥着重要作用。腾讯云提供了强大的语音识别服务&#…...

基于 Vue3、Vite 和 TypeScript 实现开发环境下解决跨域问题,实现前后端数据传递

引言 本文介绍如何在开发环境下解决 Vite 前端&#xff08;端口 3000&#xff09;和后端&#xff08;端口 80&#xff09;之间的跨域问题&#xff1a; 在开发环境中&#xff0c;前端使用的 Vite 端口与后端端口不一致&#xff0c;会产生跨域错误提示&#xff1a; Access to X…...

前端面筋(持续更新)

额外面筋 get和post的区别&#xff1f;怎么理解get能被缓存&#xff1f; get请求和post同属于http中的两种请求&#xff0c;在传输上没有什么区别&#xff0c;只是约定有所不同get请求一般用于向服务器请求数据 post请求一般用于向服务器提交数据get请求的参数一般不安全&…...

深度学习-迁移学习

深度学习中的迁移学习是通过在大规模数据上训练的模型&#xff0c;将其知识迁移到数据相对较少的相关任务中&#xff0c;能显著提升目标任务的模型性能。 一、迁移学习的核心概念 源任务&#xff08;Source Task&#xff09;与目标任务&#xff08;Target Task&#xff09;&…...

6.0、静态路由

路由器最主要的功能就是转发数据包。路由器转发数据包时需要查找路由表&#xff08;你可以理解为地图&#xff09;&#xff0c;管理员可以直接手动配置路由表&#xff0c;这就是静态路由。 1.什么是路由&#xff1f; 在网络世界中&#xff0c;路由是指数据包在网络中的传输路…...

Redis学习:BitMap/HyperLogLog/GEO案例 、布隆过滤器BloomFilter、缓存预热+缓存雪崩+缓存击穿+缓存穿透

Redis学习 文章目录 Redis学习1、BitMap/HyperLogLog/GEO案例2. 布隆过滤器BloomFilter3. 缓存预热缓存雪崩缓存击穿缓存穿透 1、BitMap/HyperLogLog/GEO案例 真实需求面试题 亿级数据的收集清洗统计展现对集合中数据进行统计&#xff0c;基数统计&#xff0c;二值统计&#xf…...

Lua数据类型

Lua 语言 数据类型 Lua 有以下数据类型&#xff1a; nil&#xff1a;表示一个无效值&#xff0c;相当于 NULL。boolean&#xff1a;true 或 false。number&#xff1a;整数或浮点数。string&#xff1a;字符串。function&#xff1a;函数。userdata&#xff1a;用户数据。th…...

CSS中的背景色和前景色

目录 1 对比度的计算1.1 亮度计算1.2 对比度比率 2 在线计算对比度 在我们的样式设计中&#xff0c;通常会有背景色和前景色的概念。前景色我们通常用来设置文本的颜色&#xff0c;而背景色通常是文本的所在容器的颜色。比如如果我们把文本放在普通容器里&#xff0c;那普通容器…...

伊莱亚斯 M. 斯坦恩(Elias M. Stein)《复分析》与《实分析》教材

分析学大师Elias M. Stein&#xff08;曾是陶哲轩的老师&#xff09;&#xff0c;写了四本分析学系列教材&#xff0c;统称为普林斯顿分析学讲座&#xff08;Princeton Lectures in Analysis&#xff09;。他们分别是&#xff1a; I Fourier Analysis&#xff1a;An Introduct…...

UCLA、MIT数学家推翻39年经典数学猜想!AI证明卡在99.99%,人类最终证伪

39年来一个看似理所当然的数学理论&#xff0c;刚刚被数学家证伪&#xff01;UCLA和MIT的研究者证实&#xff1a;概率论中众所周知的假设「上下铺猜想」是错的。有趣的是&#xff0c;他们用AI已经证明到了99.99%的程度&#xff0c;但最终&#xff0c;靠的还是理论论证。 又一个…...

大厂面试真题-很多系统会使用netty进行长连接,连接太多会有问题吗

使用Netty进行长连接时&#xff0c;机器数量过多确实可能会因为连接数量过多而引发问题。这些问题主要涉及系统资源消耗、连接管理、性能优化等方面。以下是对这些潜在问题的详细分析&#xff1a; 一、系统资源消耗 文件句柄限制&#xff1a; 在Linux等操作系统中&#xff0c;…...

Android RecyclerView ,使用ItemDecoration设置边距的大坑:左右边距不均匀/不同,已解决。

写在前面:最近有一个需求,在长宽固定的一块区域内,使用RecyclerView实现APP显示界面,考虑一下使用了网格布局GridLayoutManager,弄成5列的网格。设置边距的时候,使用ItemDecoration设置上、左边距。但是恶心的事情发生了,明明所有Item都设置了同样的左边距,但是只有第一…...

系统上云-流量分析和链路分析

优质博文&#xff1a;IT-BLOG-CN 一、流量分析 【1】流量组成&#xff1a; 按协议划分&#xff0c;流量链路可分为HTTP、SOTP、QUIC三类。 HTTPSOTPQUIC场景所有HTTP请求&#xff0c;无固定场景国内外APP等海外APP端链路选择DNS/CDN(当前特指Akamai)APP端保底IP列表/动态IP下…...

Apache 配置出错常见问题及解决方法

Apache 配置出错常见问题及解决方法 一、端口被占用问题 问题描述:在启动 Apache 时,出现“Address already in use”或类似的错误提示,这意味着 Apache 想要使用的端口已经被其他程序占用,导致 Apache 无法正常启动。原因分析: 系统中已经有其他的应用程序在使用 Apache…...

DGL库之dgl.function.u_mul_e(代替dgl.function.src_mul_edge)

DGL库之dgl.function.u_mul_e 语法格式例子 语法格式 dgl.function.u_mul_e代替了dgl.function.src_mul_edge dgl.function.u_mul_e(lhs_field, rhs_field, out)一个用于计算消息传递的内置函数&#xff0c;它通过对源节点&#xff08;u&#xff09;和边&#xff08;e&#x…...

题目练习之二叉树那些事儿

♥♥♥~~~~~~欢迎光临知星小度博客空间~~~~~~♥♥♥ ♥♥♥零星地变得优秀~也能拼凑出星河~♥♥♥ ♥♥♥我们一起努力成为更好的自己~♥♥♥ ♥♥♥如果这一篇博客对你有帮助~别忘了点赞分享哦~♥♥♥ ♥♥♥如果有什么问题可以评论区留言或者私信我哦~♥♥♥ 知道了二叉树的结…...

数字马力二面面试总结

24.03.07数字马力二面面试总结 前段时间找工作,做的一些面试笔记总结 大家有面试录音或者记录的也可以发给我,我来整理答案呀 数字马力二面面试总结 24.03.07数字马力二面面试总结你可以挑一个你的最有挑战性的,有难度的,最具有复杂性的项目,可以简单说一下。有没有和算…...

优化图片大小的方法

不能起到优化图片大小的方法有&#xff08;C&#xff09; A.减少每个像素点能够显示的颜色 B.减少像素点 C.使用ajax加载 D.使用WebP格式 C. 使用Ajax加载 Ajax是一种用于在网页中异步加载数据的技术&#xff0c;与图片大小的优化关系不大。它主要用于提高网页的加载效率&…...

DevOps-课堂笔记

各种 aaS 类比于计算机网络的 OSI 参考模型&#xff0c;一个软件应用项目需要不同的支撑层&#xff0c;例如从下至上大概需要&#xff1a; 硬件层面的服务器针对硬件做弹性分配的虚拟化机制&#xff0c;例如虚拟机在虚拟化环境内运行的 OS支撑软件应用的中间件&#xff0c;例…...

三维GIS开发cesium智慧地铁教程(5)Cesium相机控制

一、环境搭建 <script src"../cesium1.99/Build/Cesium/Cesium.js"></script> <link rel"stylesheet" href"../cesium1.99/Build/Cesium/Widgets/widgets.css"> 关键配置点&#xff1a; 路径验证&#xff1a;确保相对路径.…...

2025 后端自学UNIAPP【项目实战:旅游项目】6、我的收藏页面

代码框架视图 1、先添加一个获取收藏景点的列表请求 【在文件my_api.js文件中添加】 // 引入公共的请求封装 import http from ./my_http.js// 登录接口&#xff08;适配服务端返回 Token&#xff09; export const login async (code, avatar) > {const res await http…...

【单片机期末】单片机系统设计

主要内容&#xff1a;系统状态机&#xff0c;系统时基&#xff0c;系统需求分析&#xff0c;系统构建&#xff0c;系统状态流图 一、题目要求 二、绘制系统状态流图 题目&#xff1a;根据上述描述绘制系统状态流图&#xff0c;注明状态转移条件及方向。 三、利用定时器产生时…...

A2A JS SDK 完整教程:快速入门指南

目录 什么是 A2A JS SDK?A2A JS 安装与设置A2A JS 核心概念创建你的第一个 A2A JS 代理A2A JS 服务端开发A2A JS 客户端使用A2A JS 高级特性A2A JS 最佳实践A2A JS 故障排除 什么是 A2A JS SDK? A2A JS SDK 是一个专为 JavaScript/TypeScript 开发者设计的强大库&#xff…...

使用LangGraph和LangSmith构建多智能体人工智能系统

现在&#xff0c;通过组合几个较小的子智能体来创建一个强大的人工智能智能体正成为一种趋势。但这也带来了一些挑战&#xff0c;比如减少幻觉、管理对话流程、在测试期间留意智能体的工作方式、允许人工介入以及评估其性能。你需要进行大量的反复试验。 在这篇博客〔原作者&a…...

【无标题】路径问题的革命性重构:基于二维拓扑收缩色动力学模型的零点隧穿理论

路径问题的革命性重构&#xff1a;基于二维拓扑收缩色动力学模型的零点隧穿理论 一、传统路径模型的根本缺陷 在经典正方形路径问题中&#xff08;图1&#xff09;&#xff1a; mermaid graph LR A((A)) --- B((B)) B --- C((C)) C --- D((D)) D --- A A -.- C[无直接路径] B -…...

搭建DNS域名解析服务器(正向解析资源文件)

正向解析资源文件 1&#xff09;准备工作 服务端及客户端都关闭安全软件 [rootlocalhost ~]# systemctl stop firewalld [rootlocalhost ~]# setenforce 0 2&#xff09;服务端安装软件&#xff1a;bind 1.配置yum源 [rootlocalhost ~]# cat /etc/yum.repos.d/base.repo [Base…...

群晖NAS如何在虚拟机创建飞牛NAS

套件中心下载安装Virtual Machine Manager 创建虚拟机 配置虚拟机 飞牛官网下载 https://iso.liveupdate.fnnas.com/x86_64/trim/fnos-0.9.2-863.iso 群晖NAS如何在虚拟机创建飞牛NAS - 个人信息分享...

Proxmox Mail Gateway安装指南:从零开始配置高效邮件过滤系统

&#x1f49d;&#x1f49d;&#x1f49d;欢迎莅临我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐&#xff1a;「storms…...

抽象类和接口(全)

一、抽象类 1.概念&#xff1a;如果⼀个类中没有包含⾜够的信息来描绘⼀个具体的对象&#xff0c;这样的类就是抽象类。 像是没有实际⼯作的⽅法,我们可以把它设计成⼀个抽象⽅法&#xff0c;包含抽象⽅法的类我们称为抽象类。 2.语法 在Java中&#xff0c;⼀个类如果被 abs…...