React中OnClick触发renderReplies无效,点击展示回复功能异常
解决React点击展开评论回复的问题
你的问题核心是直接调用renderReplies返回JSX,但没有把这些JSX挂载到DOM中——React的渲染完全依赖状态驱动,点击事件里只执行函数不会触发重新渲染,自然看不到回复。以下是不用display: none的解决方案:
核心思路
用状态记录每个回复的展开状态,点击按钮时切换状态,React会根据状态变化自动渲染对应的回复内容。
修改后的代码
import { useState } from 'react'; import ReactMarkdown from 'react-markdown'; import ImArrowUp from 'react-icons/im'; import HiArrowNarrowRight from 'react-icons/hi'; const CommentSection = () => { // 用对象存储每个回复的展开状态,key用回复的唯一id const [expandedReplies, setExpandedReplies] = useState({}); // 切换回复展开状态的函数 const toggleReplyExpansion = (replyId) => { setExpandedReplies(prev => ({ ...prev, [replyId]: !prev[replyId] })); }; // 递归渲染回复 const renderReplies = (comment) => { if (!comment.data.replies) return null; return ( <div className="reply"> {comment.data.replies.data.children.map(reply => { if (!reply.data.body) return null; const replyId = reply.data.id; return ( <div className="comment-card" key={replyId}> <span className="comment-author">{reply.data.author}</span> <ReactMarkdown>{reply.data.body}</ReactMarkdown> <div className="upvotes"> <ImArrowUp id="comment-arrow-icon" /> {reply.data.score} </div> {/* 显示展开/收起按钮 */} {showMoreReplies(reply)} {/* 状态为展开时,渲染子回复 */} {expandedReplies[replyId] && renderReplies(reply)} </div> ); })} </div> ); }; const showMoreReplies = (reply) => { if (!reply.data.replies) return null; const replyId = reply.data.id; return ( <span className="show-all-replies" onClick={() => toggleReplyExpansion(replyId)} > {/* 根据状态切换按钮文本 */} {expandedReplies[replyId] ? 'Hide replies' : 'Show more replies'} <HiArrowNarrowRight className="show-more-replies-arrow" /> </span> ); }; // 这里替换为你的父评论渲染逻辑 return ( <div className="comment-section"> {/* {parentComments.map(comment => ( <div className="comment-card" key={comment.data.id}> <span className="comment-author">{comment.data.author}</span> <ReactMarkdown>{comment.data.body}</ReactMarkdown> <div className="upvotes"> <ImArrowUp id="comment-arrow-icon" /> {comment.data.score} </div> {showMoreReplies(comment)} {expandedReplies[comment.data.id] && renderReplies(comment)} </div> ))} */} </div> ); }; export default CommentSection;
关键修改点
- 新增
expandedReplies状态:用对象存储每个回复的展开状态,key用回复的唯一id,确保每个回复的状态独立。 - 新增
toggleReplyExpansion函数:点击按钮时切换对应回复的展开状态,触发React重新渲染。 - 修改
renderReplies:在评论卡片中,根据expandedReplies的状态决定是否渲染子回复。 - 修改
showMoreReplies:点击时调用状态切换函数,而非直接调用renderReplies,同时根据状态切换按钮文本(可选优化)。
这样实现完全由状态驱动渲染,不需要操作DOM或用display: none,适合大量评论的场景,每个回复的展开状态都是独立维护的。
内容的提问来源于stack exchange,提问作者araghast94
相关产品推荐
相关产品推荐

