【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>
  )
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Linux socket编程(11):Unix套接字编程及通信例子

Unix套接字是一种用于在同一台计算机上的进程间通信的一种机制。它是Linux和其他类Unix系统中的一项特性&#xff0c;通过在文件系统中创建特殊的套接字文件&#xff0c;进程可以通过这些套接字文件进行通信。 文章目录 1 Unix和TCP套接字对比2 Unix套接字初始化流程3 例:服务端…

【springboot】整合redis和定制化

1.前提条件:docker安装好了redis,确定redis可以访问 可选软件: 2.测试代码 (1)redis依赖 org.springframework.boot spring-boot-starter-data-redis (2)配置redis &#xff08;3&#xff09; 注入 Resource StringRedisTemplate stringRedisTemplate; 这里如果用Autowi…

HarmonyOS学习--了解基本工程目录

1.工程级目录 工程的目录结构如下&#xff1a; 其中详细如下&#xff1a; AppScope中存放应用全局所需要的资源文件。entry是应用的主模块&#xff0c;存放HarmonyOS应用的代码、资源等。oh_modules是工程的依赖包&#xff0c;存放工程依赖的源文件。build-profile.json5是工…

FPGA实现电机位置环、速度环双闭环PID控制

一、设计思路 主要设计思路就是根据之前写的一篇FPGA实现电机转速PID控制&#xff0c;前面已经实现了位置环的控制&#xff0c;思想就是通过电机编码器的当前位置值不断地修正PID去控制速度。 那为了更好的实现控制&#xff0c;可以在位置环后加上速度环&#xff0c;实现电机位…

【S32K3环境搭建】-0.2-安装S32DS product updates和 packages

目录 1 安装S32DS product updates和 packages 1.1 方法一&#xff1a;通过S32DS Extensions and Updates安装product updates和 packages 1.2 方法二&#xff1a;通过Install New Software…安装product updates和 packages 2 S32DS product updates和 packages安装后的效…

1-4节电池升降压充电IC解决方案

描述 MP2760是一款集成窄电压DC&#xff08;NVDC&#xff09;电源路径管理功能和USB On-the-Go(OTG)功能的升降压充电IC&#xff0c;兼容USB PD&#xff0c;适用于单节至4节串联的电池包应用。该芯片的充电输入电压范围广&#xff0c;可支持最高22V。 当启用电池放电模式&…

网络安全威胁——中间人攻击

中间人攻击 1. 定义2. 中间人攻击如何工作3. 常见中间人攻击类型4. 如何防止中间人攻击 1. 定义 中间人攻击&#xff08;Man-in-the-Middle Attack&#xff0c;简称MITM&#xff09;&#xff0c;是一种会话劫持攻击。攻击者作为中间人&#xff0c;劫持通信双方会话并操纵通信过…

Java数据结构之《最短路径》(难度系数100)

一、前言&#xff1a; 这是怀化学院的&#xff1a;Java数据结构中的一道难度偏难(偏难理解)的一道编程题(此方法为博主自己研究&#xff0c;问题基本解决&#xff0c;若有bug欢迎下方评论提出意见&#xff0c;我会第一时间改进代码&#xff0c;谢谢&#xff01;) 后面其他编程题…

Android Chips(标签)

目录 一、流式布局标签发展历程 二、类型及使用 2.1 Chip.Action(默认值) 2.2 Chip.Entry 2.3 Chip.Filter 2.4 Chip.Choice 三、常用事件 3.1 OnClickListener 3.2 OnCheckedChangeListener 3.3 OnCloseIconClickListener 四、ChipGroup 4.1 ChipGroup Chip.Choi…

计算机组成学习-中央处理器总结

复习本章时&#xff0c;思考以下问题&#xff1a; 1)CPU分为哪几部分&#xff1f;分别实现什么功能&#xff1f; 2)指令和数据均存放在内存中&#xff0c;计算机如何从时间和空间上区分它们是指令还是数据&#xff1f; 3)什么是指令周期、机器周期和时钟周期&#xff1f;它们之…

java小工具util系列3:JSON转实体类对象工具

文章目录 准备工作1.JSONObject获取所有的key2.集合中实体对象转换 list中Enrey转Dto3.字符串转List<BusyTimeIndicatorAlarmThreshold>4.json字符串转JSONObject5.list根据ids数组过滤list6.json字符串转JavaBean对象7.json对象转javabean8.jsonObject转map9.List\<U…

IDEA中,光标移动快捷键(Shift + 滚轮前后滚动:当前文件的横向滚动轴滚动。)

除此之外&#xff0c;其他常用的光标移动快捷键包括&#xff1a; Shift 滚轮前后滚动&#xff1a;当前文件的横向滚动轴滚动。Shiftenter&#xff1a;快速将鼠标移动到下一行。Ctrl ]&#xff1a;移动光标到当前所在代码的花括号结束位置。Ctrl 左方向键&#xff1a;光标跳转…

IDEA插件配置--maven篇

仓库地址 IDEA中maven插件仓库默认地址&#xff1a;C:\Users\Administrator.m2\repository 在D盘新建一个文件夹用做本地仓库地址&#xff0c;例如 D:\Program Files\maven\repository&#xff0c;将原先C盘路径下的repository拷贝到D盘 修改settings.xml配置文件 镜像地…

基于微服务架构的外卖系统源码开发

在当前互联网时代&#xff0c;外卖行业蓬勃发展&#xff0c;用户对于高效、智能的外卖服务需求不断增加。为了满足这一需求&#xff0c;采用微服务架构的外卖系统成为了开发的主流方向。本文将探讨基于微服务的外卖系统源码开发&#xff0c;涉及到关键技术和示例代码。 1. 微…

SpringBoot3-快速体验

1、pom.xml <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0"xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation"http://maven.apache.org/POM/4.0.…

搞笑视频无水印下载,高清无水印视频网站!

搞笑视频无水印下载这件事情一直困扰了广大网友&#xff0c;每当看见好玩好笑的搞笑视频然而下载下来的时候&#xff0c;要么画质模糊就带有水印今天分享大家几个搞笑视频无水印下载方法。 这是一个非常良心的搞笑视频无水印下载小程序水印云&#xff0c;它支持图片去水印、视…

Flutter桌面应用程序定义系统托盘Tray

文章目录 概念实现方案1. tray_manager依赖库支持平台实现步骤 2. system_tray依赖库支持平台实现步骤 3. 两种方案对比4. 注意事项5. 话题拓展 概念 系统托盘&#xff1a;系统托盘是一种用户界面元素&#xff0c;通常出现在操作系统的任务栏或桌面顶部。它是一个水平的狭长区…

vscode git管理

vscode添加了git管理 1、如下按钮&#xff0c;可以看到本次的修改部分 2、安装git history 就可以查看每次的不同部分了

阿里云环境下的配置DNS和SLB的几种实践示例

一、背景 对于大多中小型公司来说&#xff0c;生产环境大多是购买阿里云或者腾讯云等等&#xff0c;也就存在以下需求&#xff1a; 外网域名内网域名SLB容器化部署 特别是前两项&#xff0c;一定是跳不过的。容器化部署&#xff0c;现在非K8S莫属了。 既然是购买阿里云&…

Codeforces Round 913 (Div. 3)(A~G)

1、编程模拟 2、栈模拟 3、找规律&#xff1f;&#xff08;从终止状态思考&#xff09; 4、二分 5、找规律&#xff0c;数学题 6、贪心&#xff08;思维题&#xff09; 7、基环树 A - Rook 题意&#xff1a; 直接模拟 // Problem: A. Rook // Contest: Codeforces - C…