React 评论组件:实现喜欢和不喜欢功能并优化性能
import { useState } from 'react'; import avatar from './images/coc.png'; import './index.scss'; // 评论列表 const defaultList = [ { // 评论id rpid: 3, // 用户信息 user: { uid: '13258165', avatar: 'https://yjy-teach-oss.oss-cn-beijing.aliyuncs.com/reactbase/comment/zhoujielun.jpeg', uname: '周杰伦', }, // 评论内容 content: '哎哟,不错哦', // 评论时间 ctime: '2022-10-18 08:15', // 喜欢数量 like: 98, // 0:未表态 1: 喜欢 2: 不喜欢 action: 0, }, { rpid: 2, user: { uid: '36080105', avatar: 'https://yjy-teach-oss.oss-cn-beijing.aliyuncs.com/reactbase/comment/xusong.jpeg', uname: '许嵩', }, content: '我寻你千百度 日出到迟暮', ctime: '2022-11-13 11:29', like: 88, action: 2, }, { rpid: 1, user: { uid: '30009257', avatar, uname: '黑马前端', }, content: '学前端就来黑马', ctime: '2022-10-19 09:00', like: 66, action: 1, }, ]; // 当前用户 const profile = { // id uid: '30009257', // 头像 avatar, // 昵称 uname: '黑马前端', };
// 导航tabs数组
const tabs = [
{
type: 'hot',
text: '最热',
},
{
type: 'time',
text: '最新',
},
];
const MyCommentary = () => {
//js内置时间过滤
// Vue.filter('dateFormat', function (originVal) {
// const dt = new Date(originVal)
// const y = dt.getFullYear()
// const m = (dt.getMonth() + 1 + '').padStart(2, '0')
// const d = (dt.getDate() + '').padStart(2, '0')
// const hh = (dt.getHours() + '').padStart(2, '0')
// const mm = (dt.getMinutes() + '').padStart(2, '0')
// const ss = (dt.getSeconds() + '').padStart(2, '0')
// return ${y}-${m}-${d} ${hh}:${mm}:${ss}
// })
function filternumber(originVal) {
const dt = new Date(originVal)
const y = dt.getFullYear()
const m = (dt.getMonth() + 1 + '').padStart(2, '0')
const d = (dt.getDate() + '').padStart(2, '0')
const hh = (dt.getHours() + '').padStart(2, '0')
const mm = (dt.getMinutes() + '').padStart(2, '0')
return ${y}-${m}-${d} ${hh}:${mm}
}
const [comment, setComment] = useState(defaultList)
// const [arr, setArr] = useState(tabs)
// 点击最新最热
const [count, setCount] = useState('hot')
const handlick = (type) => {
setCount(type)
// console.log(type)
if (type === 'hot') {
comment.sort((a, b) => b.like - a.like)
} else {
comment.sort((a, b) => new Date(b.ctime) - new Date(a.ctime))
}
}
// 点击删除
const del = (uid) => {
setComment(comment.filter((item) => item.rpid !== uid))
}
// 点击发布
const handleinput = () => {
let value = document.querySelector('.reply-box-textarea').value
if (!value) {
return
}
let myname = {
user: {
uid: '30009257',
avatar,
uname: '黑马前端',
},
rpid: comment.length + 1,
content: value,
ctime: filternumber(new Date()) + '',
like: 0,
action: 0,
}
setComment([...comment, myname])
document.querySelector('.reply-box-textarea').value = ''
}
// 喜欢和不喜欢点击
const handleLike = (item, num) => {
if (item.action === 0) { // 未表态
setComment(prevComment => {
return prevComment.map(commentItem => {
if (commentItem.rpid === item.rpid) {
return {
...commentItem,
like: commentItem.like + num,
action: num > 0 ? 1 : 2
};
} else {
return commentItem;
}
});
});
}
}
return (
- 评论 {/ 评论数量 */} {comment.length}
- {tabs.map((item, index) => ( <div className={count === item.type ? 'nav-item active' : 'nav-item'} key={index} onClick={() => handlick(item.type)} > {item.text}
<div className="reply-wrap">
{/* 发表评论 */}
<div className="box-normal">
{/* 当前用户头像 */}
<div className="reply-box-avatar">
<div className="bili-avatar">
<img
className="bili-avatar-img"
src={avatar}
alt="用户头像"
/>
</div>
</div>
<div className="reply-box-wrap">
{/* 评论框 */}
<textarea
className="reply-box-textarea"
placeholder="发一条友善的评论"
/>
{/* 发布按钮 */}
<div
className="reply-box-send"
onClick={() => handleinput()}
>
<div className="send-text">发布</div>
</div>
</div>
</div>
{/* 评论列表 */}
{comment.map((item, index) => (
<div
className="reply-list"
key={index}
>
{/* 评论项 */}
<div className="reply-item">
{/* 头像 */}
<div className="root-reply-avatar">
<div className="bili-avatar">
<img
className="bili-avatar-img"
src={item.user.avatar}
alt="头像"
/>
</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.slice(5)}</span>
{/* 喜欢 */}
<span className="reply-like">
{/* 选中类名: liked */}
<i
onClick={() => handleLike(item, 1)}
className={
item.action === 1
? 'icon like-icon liked'
: 'icon like-icon'
}
/>
<span>{item.like}</span>
</span>
{/* 不喜欢 */}
<span className="reply-dislike">
{/* 选中类名:icon dislike-icon disliked */}
<i
className={
item.action === 2
? 'icon dislike-icon disliked'
: 'icon dislike-icon'
}
/>
</span>
{item.user.uid === profile.uid && (
<span
className="delete-btn"
onClick={() => del(item.rpid)}
>
删除
</span>
)}
</div>
</div>
</div>
</div>
</div>
))}
<div className="reply-none">暂无评论</div>
</div>
</div>
) } export default MyCommentary
原文地址: https://www.cveoy.top/t/topic/qcCn 著作权归作者所有。请勿转载和采集!