【React】使用react hooks实现评论示例

动态效果展示

实现功能

1、渲染评论列表
2、删除评论
3、渲染导航栏和高亮
4、评论列表排序功能
5、获取评论
6、点击发布按钮发布评论
7、清空输入框
8、重新聚焦

实现代码

1、需要引入

import React, { useRef, useState } from 'react'
import avatar from "../logo.png" //头像
import "./css/index.css" //样式

2、样式----[./css/index.css]

* {margin: 0;padding: 0;
}.comment-box {width: 1000px;margin: 20px auto;height: 200px;
}/* 导航栏 */
.comment-tabs {display: flex;align-items: end;font-weight: normal;margin-bottom: 20px;
}.tabs-left {margin-right: 20px;font-size: 14px;
}.tabs-left p span {margin-left: 6px;color: #666;font-size: 10px;
}.tabs-right {display: flex;color: #666;font-size: 10px;
}.tabs-right .active {color: #08a17d;font-weight: 500;
}.tabs-right div span {display: inline-block;margin: 0 6px;height: 6px;border-left: 1px solid #666;
}.tabs-right div:last-child span {border: none;
}/* 发表评论 */
.comment-send {display: flex;align-items: center;justify-content: space-between;height: 40px;
}.avatar {width: 35px;height: 35px;margin-left: 10px;overflow: hidden;border-radius: 35px;border: 1px solid #08a17d;
}.avatar img {width: 100%;height: 100%;
}.comment-send .content {flex: 1;margin: 0 10px;padding: 0 10px;height: 100%;line-height: 40px;border: none;background: #eee;border-radius: 4px;border: 1px solid #eee;
}.comment-send .content:hover {background: none;
}.comment-send .button {width: 80px;height: 100%;color: #fff;text-align: center;line-height: 40px;background: #08a17d;border-radius: 4px;
}.comment-send .button:hover {cursor: pointer;
}/* 评论列表 */
.comment-list {margin-top: 20px;
}.comment-item {display: flex;margin-bottom: 20px;padding-bottom: 10px;border-bottom: 1px solid #eee;
}.comment-item .right {flex: 1;margin-left: 10px;font-size: 10px;color: #666;line-height: 20px;
}.comment-item .right .content {color: #000;font-weight: 500;font-size: 12px;
}.comment-item .right .like {margin: 0 10px;
}.comment-item .right .delete:hover {cursor: pointer;
}

3、数据

// 当前用户数据
const user = {uid: "10009",avatar,uname: "jock"
}// 导航
const tabs = [{name: "最新",id: 1},{name: "最热",id: 2},
]
// 评论列表
const comment_list = [{id: "1",content: "真不错",time: "2020/1/1 12:00:00",like: 1,user: {uid: "10029",avatar,uname: "jock"}},{id: "2",content: "没毛病",time: "2020/11/01 12:00:00",like: 3,user: {uid: "10009",avatar,uname: "jock"}},{id: "3",content: "真棒",time: "2020/8/21 12:00:00",like: 10,user: {uid: "10008",avatar,uname: "alen"}},
]

4、逻辑处理

export default function Comment() {const [list, setList] = useState(comment_list.sort((a, b) => new Date(b.time) - new Date(a.time)));const [type, setType] = useState(1);const [content, setContent] = useState("");const inputRef = useRef();// tab切换const handleChange = (id) => {setType(id)if (id === 1) {setList(list.sort((a, b) => new Date(b.time) - new Date(a.time)))} else {setList(list.sort((a, b) => b.like - a.like))}}//发布const handleSend = () => {setList([...list, {id: Math.random().toString().slice(2),content,time: new Date().toLocaleString(),like: 0,user}])setContent("");inputRef.current.focus();}// 删除const handleDel = (id) => {setList(list.filter(item => item.id !== id))}return (<div className='comment-box'>{/* 导航栏 */}<div className='comment-tabs'><div className='tabs-left'><p>评论<span>{list.length}</span></p></div><div className='tabs-right'>{tabs.map(item =><div key={item.id} onClick={() => handleChange(item.id)} className={item.id === type ? 'active' : ''}>{item.name} <span></span></div>)}</div></div><div className='comment-wrap'>{/* 发表评论 */}<div className='comment-send'><div className='avatar'><img src={user.avatar} alt='' /></div><textarea className='content' ref={inputRef} value={content} onChange={(e) => setContent(e.target.value)} placeholder='下面我简单说两句' /><div className='button' onClick={() => handleSend()}>发布</div></div>{/* 评论列表 */}<div className='comment-list'>{list.map(item =><div className='comment-item' key={item.id}><div className='avatar'><img src={item.user.avatar} alt='' /></div><div className='right'><p className='username'>{item.user.uname}</p><p className='content'>{item.content}</p><p><span className='time'>{item.time}</span><span className='like'>点赞数: {item.like}</span>{item.user.uid === user.uid && <span className='delete' onClick={() => handleDel(item.id)}>删除</span>}</p></div></div>)}</div></div></div>)
}

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

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

相关文章

[动态规划及递归记忆搜索法]2.插入乘号

插入乘号 题目描述 给定一个非负整数&#xff0c;用k个乘号将其分割&#xff0c;使得乘积最大。 例如&#xff1a;在整数12345中插入两个乘号&#xff0c;有以下插入法&#xff1a; 1*2*345 1*23*45 1*234*5 12*3*45 12*34*5 123*4*5 其中最大值是123*4*5 2460 关于输入 一…

前端小技巧: 面向切面编程在前端代码中的应用

面向切面编程 面向切面编程在java中提出这类概念但是在js没有束缚和约定&#xff0c;只需要按编程思想来实现原理在js中使用function或class实现面向切面编程 面向切面概念 AOP (Aspect Oriented Programming) 面向切面编程主要实现目的是针对业务处理过程中的切面进行提取&…

第18章:随堂复习与企业真题(JDK8-17新特性)

第18章&#xff1a;随堂复习与企业真题&#xff08;JDK8-17新特性&#xff09; 一、随堂复习 1. JDK新特性的概述 几个重要的版本 jdk 5.0 / jdk 8.0 &#xff1a;里程碑式的版本jdk9.0 开始每6个月发布一个新的版本LTS : jdk8 、 jdk 11 、 jdk 17 如何学习新特性 > 角…

Android安全学习路标

1. Android操作系统基础知识 首先&#xff0c;你需要建立坚实的Android操作系统基础知识&#xff0c;包括Android架构、进程和内存管理、应用组件和权限模型等基本概念。 2. 安全防范理论 学习关于安全防范理论的基础知识&#xff0c;包括常见的威胁模型、攻击类型和安全风险…

Python-猜数字游戏

&#x1f388; 博主&#xff1a;一只程序猿子 &#x1f388; 博客主页&#xff1a;一只程序猿子 博客主页 &#x1f388; 个人介绍&#xff1a;爱好(bushi)编程&#xff01; &#x1f388; 创作不易&#xff1a;喜欢的话麻烦您点个&#x1f44d;和⭐&#xff01; &#x1f388;…

免费的AI改写文案软件,热门AI改写文案软件【2024】

在数字化时代&#xff0c;文案创作变得更为便捷&#xff0c;其中AI改写文案软件的兴起为写作者们带来了全新的创作体验。这些工具通过智能算法和自然语言处理技术&#xff0c;能够快速改写文本&#xff0c;提高创作效率。本文将深入探讨AI改写文案软件的现状&#xff0c;介绍一…

LeetCode题:174. 地下城游戏

目录 一、题目要求 二、解题思路 &#xff08;1&#xff09;状态表示 &#xff08;2&#xff09;状态转移方程 &#xff08;3&#xff09;初始化dp表 &#xff08;4&#xff09;填表顺序 &#xff08;5&#xff09;返回值 三、代码 一、题目要求 174. 地下城游戏 恶魔们…

swagger入门

swagger入门 pom依赖 不用专门导入swagger 因为springboot已经将它集成了 org.springframework.boot spring-boot-starter com.github.xiaoymin knife4j-spring-boot-starter Swagger配置类 Configuration public class SwaggerConfig { // 创建并配置Docket Bean&#xf…

snakeyaml编辑yaml文件并覆盖注释

文章目录 前言技术积累实战演示1、引入maven依赖2、覆盖注释工具类3、snakeyaml工具类4、测试用例5、测试效果展示 写在最后 前言 最近在做一个动态整合框架的项目&#xff0c;需要根据需求动态组装各个功能模块。其中就涉及到了在application.yaml中加入其他模块的配置&#…

TCP传输层详解(计算机网络复习)

介绍&#xff1a;TCP/IP包含了一系列的协议&#xff0c;也叫TCP/IP协议族&#xff0c;简称TCP/IP。该协议族提供了点对点的连接机制&#xff0c;并将传输数据帧的封装、寻址、传输、路由以及接收方式都予以标准化 TCP/IP的分层模型 在讲TCP/IP协议之前&#xff0c;首先介绍一…

力扣贪心题解 跳跃游戏

55. 跳跃游戏 - 力扣&#xff08;LeetCode&#xff09; 给你一个非负整数数组 nums &#xff0c;你最初位于数组的 第一个下标 。数组中的每个元素代表你在该位置可以跳跃的最大长度。 判断你是否能够到达最后一个下标&#xff0c;如果可以&#xff0c;返回 true &#xff1b…

信息系统开发方法

企业信息系统对于企业信息化的重要意义是不言而喻的。从实际运行的效果来看&#xff0c;有些信息系统运行得很成功&#xff0c;取得了巨大的经济效益和社会效益&#xff1b;但也有些信息系统效果并不显著&#xff0c;甚至还有个别信息系统开始时还能正常运行&#xff0c;可时间…

广州数字孪生赋能工业制造,加速推进制造业数字化转型

广州数字孪生赋能工业制造&#xff0c;加速推进制造业数字化转型。数字孪生系统基于历史数据、实时数据&#xff0c;采用人工智能、大数据分析等新一代信息技术对物理实体的组成、特征、功能和性能进行数字化定义和建模。通过构建在信息世界对物理实体的等价映射&#xff0c;对…

Axure官方软件安装、汉化保姆级教程(带官方资源下载)

1.下载汉化包 百度云链接&#xff1a;https://pan.baidu.com/s/1lluobjjBZvitASMt8e0A_w?pwdjqxn 提取码&#xff1a; jqxn 2.解压压缩包 3.安装Axure 进行安装 点击next 打勾&#xff0c;然后next, 默认是c盘&#xff0c;修改成自己的文件夹&#xff08;不要什么都放c盘里…

RestTemplate硬编码的使用

RestTemplate是由Spring框架提供的一个可用于应用中调用rest服务的类它简化了与http服务的通信方式&#xff0c;统一了RESTFul的标准&#xff0c;封装了http连接&#xff0c;我们只需要传入url及其返回值类型即可。相较于之前常用的HttpClient&#xff0c;RestTemplate是一种更…

API测试基础之http协议

http简介&#xff1a; http&#xff08;超文本传输协议&#xff09;是一个简单的请求-响应协议&#xff0c;它通常运行在TCP&#xff08;传输控制协议&#xff09;之上。它指定了客户端可能发送给服务器什么样的消息以及得到什么样的响应。请求和响应消息的头以ASCII码形式给出…

远程控制如何赋能智能制造?贝锐向日葵制造业场景案例解析

随着数字化转型在制造业的不断深入&#xff0c;企业在产线端也逐渐投入更多智能化设备&#xff0c;数字化、智能化设备其中一个比较显著的优势就是可以依托互联网实现远程运维和调试&#xff0c;大大提升产线设备的稳定性和工作效率&#xff1b;而远程调试运维一个重要的实现方…

人工智能原理复习--搜索策略(一)

文章目录 上一篇搜索概述一般图搜索盲目搜索下一篇 上一篇 人工智能原理复习–确定性推理 搜索概述 问题求解分为两大类&#xff1a;知识贫乏系统&#xff08;依靠搜索技术解决&#xff09;、知识丰富系统&#xff08;依靠推理技术&#xff09; 两大类搜索技术&#xff1a; …

海思3516DV500下的目标识别算法运行评估,包含yolov7,yolov8

目前在3516DV500下&#xff0c;自己训练的模型的评估实测结果。根据实际模型会有些许差异。 涉及到技术细节的部分因为商业用途&#xff0c;有部分省略。如需相关技术服务项目合作可私信联系。 我司推出的目标识别跟踪模块&#xff0c;支持热红外、可见光主流多光谱视频输入与目…

WeiPHP 微信开发平台 SQL注入漏洞复现

0x01 产品简介 weiphp 是一个开源,高效,简洁的微信开发平台,基于 oneThink 内容管理框架实现。 0x02 漏洞概述 weiphp 微信开发平台 _send_by_group、 wp_where、 get_package_template等接口处存在 SQL 注入漏洞,攻击者利用此漏洞可获取数据库中的信息(例如,管理员后台…