React:封装一个评论回复组件

分析

用户想要一个能够显示评论列表,并且允许用户进行回复的组件。可能还需要支持多级回复,也就是对回复进行再回复。然后,我要考虑组件的结构和功能。

首先,数据结构方面,评论应该包含id、内容、作者、时间,以及可能的子回复。子回复的结构可能和评论类似,所以可以设计一个通用的结构,比如每个评论有一个replies数组,里面存放回复对象。

接下来是组件的状态管理。评论列表应该用useState来管理,这样当添加新评论或回复时,组件可以重新渲染。还需要处理用户输入,所以需要状态来保存输入的文本。

然后是UI部分。评论和回复可能需要递归渲染,因为每个回复下面可能还有更多的回复。所以可以考虑用一个递归组件来渲染评论及其子回复。每个评论项需要显示作者、内容、时间,还有一个回复按钮。点击回复按钮时,要显示一个输入框,让用户输入回复内容。

输入框部分,可能需要根据当前回复的父评论ID来判断在哪里显示输入框。例如,当点击某个评论的回复按钮时,输入框应该出现在该评论的下方。因此,需要有一个状态来跟踪当前正在回复的评论ID。

提交回复的函数需要处理两种情况:一种是直接评论,另一种是回复某个具体的评论。提交时,需要更新评论列表,添加新的回复到对应的replies数组中。这里可能需要一个函数来递归查找父评论并添加回复,或者使用辅助函数来处理嵌套结构。

样式方面,用户可能希望有不同的缩进来表示层级关系。比如,顶级评论没有缩进,一级回复缩进一定距离,二级回复再缩进更多,以此类推。可以用paddingLeft或者marginLeft来实现,根据层级动态调整。

还需要考虑组件的可定制性,比如允许用户传入自定义样式、评论和回复的渲染方法,或者回调函数当提交评论时。这样组件更灵活,用户可以根据需要调整外观和行为。

测试一下功能,比如添加评论、回复评论,确保状态更新正确,UI渲染正确。特别是多级回复的情况,要确保递归渲染正确,并且输入框出现在正确的位置。

能的优化点:使用useCallback来避免函数重复创建,提高性能。特别是提交回复的函数和回复按钮的回调函数。另外,对于深层嵌套的评论,递归渲染可能会导致性能问题,但一般情况下的评论层级不会太深,所以应该可以接受。

最后,提供示例用法,让用户知道如何传入初始数据,以及如何使用组件。可能需要提醒用户根据需要调整样式,或者处理时间格式化等问题,比如使用date-fns或其他库来格式化时间显示。

实现代码

封装一个可复用的评论回复组件,支持多级嵌套回复。以下是代码实现:

import React, { useState } from 'react';
import PropTypes from 'prop-types';// 评论项组件
const CommentItem = ({ comment,depth = 0,onReply,activeReplyId,setActiveReplyId,parentAuthor 
}) => {const maxDepth = 4; // 控制最大嵌套深度const canReply = depth < maxDepth;return (<div className="comment-item" style={{ marginLeft: depth * 32 }}><div className="comment-header"><span className="comment-author">{comment.author}</span>{parentAuthor && (<span className="reply-to">回复 @{parentAuthor}</span>)}<span className="comment-time">{comment.time}</span></div><div className="comment-content">{comment.content}</div>{canReply && (<button className="reply-btn"onClick={() => setActiveReplyId(comment.id)}>回复</button>)}{/* 回复输入框 */}{activeReplyId === comment.id && (<CommentInputonSubmit={(content) => onReply(comment.id, content)}onCancel={() => setActiveReplyId(null)}/>)}{/* 递归渲染子回复 */}{comment.replies?.map((reply) => (<CommentItemkey={reply.id}comment={reply}depth={depth + 1}onReply={onReply}activeReplyId={activeReplyId}setActiveReplyId={setActiveReplyId}parentAuthor={comment.author}/>))}</div>);
};// 评论输入框组件
const CommentInput = ({ onSubmit, onCancel }) => {const [content, setContent] = useState('');const handleSubmit = () => {if (content.trim()) {onSubmit(content);setContent('');}};return (<div className="comment-input-container"><textareavalue={content}onChange={(e) => setContent(e.target.value)}placeholder="输入评论内容..."rows={3}/><div className="input-buttons"><button onClick={handleSubmit}>提交</button><button onClick={onCancel}>取消</button></div></div>);
};// 主组件
const CommentComponent = ({ initialComments,currentUser = '匿名用户'
}) => {const [comments, setComments] = useState(initialComments);const [activeReplyId, setActiveReplyId] = useState(null);// 添加评论/回复const addComment = (content, parentId = null) => {const newComment = {id: Date.now(),author: currentUser,content,time: new Date().toLocaleString(),replies: []};if (!parentId) {setComments([...comments, newComment]);} else {const updateComments = (comments) => comments.map(comment => {if (comment.id === parentId) {return {...comment,replies: [...comment.replies, newComment]};}return {...comment,replies: updateComments(comment.replies)};});setComments(prev => updateComments(prev));}};return (<div className="comment-container"><CommentInput onSubmit={(content) => addComment(content)} /><div className="comments-list">{comments.map((comment) => (<CommentItemkey={comment.id}comment={comment}onReply={addComment}activeReplyId={activeReplyId}setActiveReplyId={setActiveReplyId}/>))}</div></div>);
};// Prop 类型校验
CommentComponent.propTypes = {initialComments: PropTypes.arrayOf(PropTypes.shape({id: PropTypes.number.isRequired,author: PropTypes.string.isRequired,content: PropTypes.string.isRequired,time: PropTypes.string,replies: PropTypes.array})),currentUser: PropTypes.string
};export default CommentComponent;

组件特性说明:

  1. 核心功能
  • 支持多级嵌套回复(默认最多4层)
  • 显示回复对象(回复 @xxx)
  • 支持自定义当前用户
  • 支持初始评论数据传入
  • 自动生成评论时间
  1. 组件结构
  • CommentComponent:主组件
  • CommentItem:单个评论项(支持递归渲染)
  • CommentInput:评论输入组件
  1. 使用示例
// 初始化数据示例
const initialComments = [{id: 1,author: '用户A',content: '第一条评论',time: '2023-08-01 10:00',replies: [{id: 2,author: '用户B',content: '第一条回复',time: '2023-08-01 10:05'}]}
];// 使用组件
<CommentComponent initialComments={initialComments}currentUser="当前用户"
/>
  1. 样式建议
.comment-container {max-width: 800px;margin: 0 auto;padding: 20px;
}.comment-item {margin: 16px 0;padding: 12px;border: 1px solid #eee;border-radius: 4px;
}.comment-header {display: flex;align-items: center;margin-bottom: 8px;color: #666;
}.comment-author {font-weight: bold;margin-right: 8px;
}.reply-to {color: #999;margin-right: 8px;
}.comment-time {font-size: 0.9em;
}.reply-btn {background: none;border: none;color: #1890ff;cursor: pointer;padding: 4px 8px;
}.comment-input-container {margin: 16px 0;
}.comment-input-container textarea {width: 100%;padding: 8px;margin-bottom: 8px;
}.input-buttons button {margin-right: 8px;padding: 4px 12px;
}
  1. 扩展建议
  • 增加点赞功能
  • 支持富文本输入
  • 添加评论删除功能
  • 支持用户头像显示
  • 增加评论加载更多功能
  • 支持@用户功能

使用时请根据实际需求调整样式和功能实现,可以通过props传递更多配置项(如最大嵌套深度、日期格式等)来增强组件的灵活性。

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

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

相关文章

wx读书某sign算法详解

未加固 版本&#xff1a;9.2.3 前置知识&#xff1a; (v41 & 0xFFFFFFFFFFFFFFFELL) 是一种高效的奇偶检查方法&#xff0c;用于判断数值 v41 是否为奇数。 std::sort<std::lessstd::string,std::string &,std::string>(a1, v6, s); 排序算法 # 完全等价的字…

Django的异步任务队列管理_Celery

1 基本原理 Celery 是一个异步任务队列&#xff0c;能够将耗时操作&#xff08;如发邮件、处理图片、网络爬虫等&#xff09;从 Django 主线程中分离出来&#xff0c;由后台的 worker 处理&#xff0c;避免阻塞请求。Celery 作为独立运行的后台进程&#xff08;Worker&#xf…

【计算机网络】Linux网络的几个常用命令

&#x1f4da; 博主的专栏 &#x1f427; Linux | &#x1f5a5;️ C | &#x1f4ca; 数据结构 | &#x1f4a1;C 算法 | &#x1f152; C 语言 | &#x1f310; 计算机网络 相关文章&#xff1a;计算机网络专栏 目录 ping&#xff08;检测网络连通性&#xff09;…

全开源、私有化部署!轻量级用户行为分析系统-ClkLog

ClkLog是一款支持私有化部署的全开源埋点数据采集与分析系统&#xff0c;兼容Web、App、小程序多端埋点&#xff0c;快速洞察用户访问路径、行为轨迹&#xff0c;并生成多维用户画像。助力中小团队搭建轻量灵活的用户行为分析平台。 为什么需要一款私有化的埋点分析系统&#x…

golang定时器的精度

以 go1.23.3 linux/amd64 为例。 定时器示例代码&#xff1a; package mainimport ("context""fmt""time" )var ctx context.Contextfunc main() {timeout : 600 * time.Secondctx, _ context.WithTimeout(context.Background(), timeout)dea…

svn 远程服务搜索功能

svn服务器没有远程搜索功能&#xff0c;靠人工检索耗时耗力&#xff0c;当服务器文件过多时&#xff0c;全部checkout到本地检索&#xff0c;耗时太久。 1. TortoiseSVN 安装注意事项 下载官网地址&#xff1a;https://tortoisesvn.en.softonic.com/download 安装时选中 co…

uniapp-商城-39-shop 购物车 选好了 进行订单确认4 配送方式2 地址页面

上面讲基本的样式和地址信息&#xff0c;但是如果没有地址就需要添加地址&#xff0c;如果有不同的地址就要选地址。 来看看处理方式&#xff0c; 1、回顾 在delivery-layout中 methods:{goAddress(){uni.navigateTo({url:"/pagesub/pageshop/address/addrlist"})…

Linux命令-iostat

iostat 命令介绍 iostat 是一个用于监控 Linux 系统输入/输出设备加载情况的工具。它可以显示 CPU 的使用情况以及设备和分区的输入/输出统计信息&#xff0c;对于诊断系统性能瓶颈&#xff08;如磁盘或网络活动缓慢&#xff09;特别有用。 语法&#xff1a; iostat [options…

vue2关于Node.js17及以上报digital envelope错误的解决办法

文章目录 简介错误原因解决方案设置环境变量修改package.json安装旧版本Node.js更新依赖项更改加密设置 简介 digital envelope routines::unsupported错误‌通常发生在Node.js版本升级到17或更高版本后&#xff0c;因为这些版本开始使用OpenSSL 3.0&#xff0c;它对算法和密钥…

LLM - Large Language Model

回顾2024&#xff1a;与LLM又相伴一年的经历与思考 - 知乎万字长文入门大语言模型&#xff08;LLM&#xff09; - 知乎“大模型本质就是两个文件&#xff01;”特斯拉前AI总监爆火LLM科普&#xff0c;时长1小时&#xff0c;面向普通大众 - 知乎大模型本质及趋势剖析&#xff0c…

Linux 内核网络协议栈中的关键数据结构:inet_skb_parm 与 ip_options

在 Linux 内核的网络协议栈中,数据包的高效处理依赖于一系列精心设计的数据结构。这些结构体不仅需要存储网络数据的元信息,还需支持复杂的协议逻辑(如路由、分片、安全策略等)。本文聚焦两个核心结构体 struct inet_skb_parm 和 struct ip_options,解析它们的设计原理、功…

如何修复卡在恢复模式下的 iPhone:简短指南

Apple 建议使用恢复模式作为最后的手段&#xff0c;以便在 iPhone 启动循环或显示 Apple 标志时恢复 iPhone。这是解决持续问题的简单方法&#xff0c;但您很少使用。但是&#xff0c;当您的 iPhone 卡住恢复模式本身时&#xff0c;您会怎么做&#xff1f;虽然 iPhone 卡在这种…

10前端项目----商品详情页/滚轮行为

商品详情页面 商品详情组件发送请求获取相应商品详情信息组件展示数据 优化一下路由配置代码滚轮自动置顶 商品详情组件 路由配置 点击商品进行跳转—将Detail组件变成路由组件 从商品到详情&#xff0c;肯定需要传参(产品ID)告诉Detail是哪个商品&#xff0c;需要展示哪个商品…

DIFY 又跟新了,来到 1.3.0 版本,看正文

欢迎来到 1.3.0 版本&#xff01;添加了各种巧妙的功能、修复了错误&#xff0c;并带来了一些新功能&#xff1a; 一、核心亮点&#xff1a; 结构化输出 1、LLM 节点新增JSON Schema编辑器&#xff0c;确保大语言模型能够返回符合预设格式的JSON数据。这一功能有助于提升数据…

git检查提交分支和package.json的version版本是否一致

这里写自定义目录标题 一、核心实现步骤‌1.安装必要依赖‌2.初始化 Husky‌3.创建校验脚本‌4.配置 lint-staged‌5.更新 Husky 钩子‌ 三、工作流程说明‌四、注意事项‌ 以下是基于 Git Hooks 的完整解决方案&#xff0c;通过 husky 和自定义脚本实现分支名与版本号一致性校…

react-navigation-draw抽屉导航

心得写在前面分享给大家&#xff1a; 我的实现方法&#xff0c;并没有完全安装官网来做&#xff0c;而是进行了简化&#xff0c;效果是一样的。没有按照官网说的修改metro.config.js文件&#xff0c;同时也没有 react-native-gesture-handler 的安装后&#xff0c;我们需要有条…

【计算机视觉】CV实战项目-高分辨率遥感图像语义分割:High-Resolution-Remote-Sensing-Semantic-Segmentation

高分辨率遥感图像语义分割技术解析与实战指南 项目背景与意义核心技术解析1. **膨胀预测&#xff08;Dilated Prediction&#xff09;**2. **后处理优化**3. **半监督学习&#xff1a;伪标签&#xff08;Pseudo Labeling&#xff09;**4. **可视化与监控** 实战指南&#xff1a…

免费送源码:Java+SSM+MySQL 基于SSM开发的校园心理咨询平台系统的设计与实现 计算机毕业设计原创定制

目 录 1 绪论 1 1.1 研究背景 1 1.2开发现状 1 1.3论文结构与章节安排 2 2 校园心理咨询平台系统系统分析 3 2.1 可行性分析 3 2.1.1 技术可行性分析 3 2.1.2 经济可行性分析 3 2.1.3 法律可行性分析 3 2.2 系统功能分析 3 2.2.1 功能性分析 4 2.2.2 非功能性分析…

学习笔记:Qlib 量化投资平台框架 — GETTING STARTED

学习笔记&#xff1a;Qlib 量化投资平台框架 — GETTING STARTED Qlib 是微软亚洲研究院开源的一个面向人工智能的量化投资平台&#xff0c;旨在实现人工智能技术在量化投资中的潜力&#xff0c;赋能研究&#xff0c;并创造价值&#xff0c;从探索想法到实施生产。Qlib 支持多种…

cmake qt 项目编译

当前MAC 编译命令 rm -rf build 删除之前build记录 mkdir build && cd build 重新生成build文件夹 cmake -DCMAKE_PREFIX_PATH"/usr/local/opt/qt" .. Cmake编译指定我的qt路径 cmake --build . 生成程序 程序生成后如此 第三方库单独下载 在CMakeLis…