You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React中传递给Props的嵌套评论数据如何实现无刷新重新渲染

问题根因

嵌套回复无法自动渲染的核心原因是:你的评论全量数据存储在父组件PostView的PostCommentData状态中,Reply组件仅接收Props做纯渲染。提交嵌套回复成功后,你没有触发PostCommentData的状态更新,React检测不到数据变化自然不会触发重渲染,只有手动刷新后重新拉取接口才能拿到最新数据。

解决方案

方案1:提交后触发全量评论刷新(实现简单)

  1. 首先在PostView中将拉取评论的方法抽离为可全局调用的函数,作为Props传给Reply组件:
///PostView.tsx
function PostView({ match }: RouteComponentProps<MatchParams>) {
  const [postData, setData] = useState()
  const [postCommentData, setPostCommentData] = useState<[]>()
  const postId = match.params.id

  // 抽离拉取评论列表的方法
  const fetchCommentList = async () => {
    const res = await axios.get(`/api/post/${postId}/comment`)
    setPostCommentData(res.data)
  }

  useEffect(() => {
    async function CallPostData(id: string) {
      const res = await axios.get(`/api/post/${id}`)
      setData(res.data)
    }
    CallPostData(postId)
    // 初始化加载评论
    fetchCommentList()
  }, [postId])

  const replyList = postCommentData?.map((item) => {
    return (
      <Reply
        key={item.commentId}
        commentId={item.commentId}
        userImage={item.userImage}
        userName={item.userName}
        comment={item.comment}
        commentTime={item.commentTime}
        commentList={item.commentList}
        MainPostId={postId}
        // 给子组件传递刷新方法
        refreshComment={fetchCommentList}
      />
    )
  })
}
  1. 改造Reply组件,在嵌套回复提交成功后调用传入的刷新方法:
//Reply.tsx
export interface IReply {
  commentId: number;
  userName: string;
  userImage: string;
  comment: string;
  commentTime: string;
  MainPostId: string;
  commentList: IArray[];
  // 新增刷新方法类型定义
  refreshComment: () => Promise<void>;
}

function Reply(props: IReply) {
  // 嵌套回复提交逻辑示例
  const submitNestedReply = async (replyContent: string) => {
    // 调用提交嵌套回复的接口
    await axios.post(`/api/comment/${props.commentId}/reply`, {
      content: replyContent
    })
    // 提交成功后触发评论列表刷新
    await props.refreshComment()
  }

  const Recomment = props.commentList.map((item) => {
    return (
      <li className="childReply_item" key={item.commentId}>
        <div className="comment_1">
          <Link to="" className="reply_thumb">
            <img
              src={
                item.userImage === null || item.userImage === "string"
                  ? "https://myrecord.s3.ap-northeast-2.amazonaws.com/7e1436db-68ea-45c5-b997-6de46f17280b.png"
                  : item.userImage
              }
            />
          </Link>
          <div className="reply_box">
            <Link to="" className="link_name">
              <span>{item.userName}</span>
            </Link>
            <p>{item.comment}</p>
            <p className="date">{item.commentTime}</p>
          </div>
        </div>
      </li>
    )
  })
}

方案2:本地更新状态(性能更优)

如果不想提交后额外发起一次全量评论拉取请求,可以直接在本地更新对应父评论的回复列表:

  1. 在PostView中新增本地更新回复列表的方法,传给Reply组件:
// PostView.tsx 新增方法
const addNestedReply = (parentCommentId: number, newReply: IArray) => {
  setPostCommentData(prev => {
    return prev.map(comment => {
      if(comment.commentId === parentCommentId) {
        return {
          ...comment,
          commentList: [...comment.commentList, newReply]
        }
      }
      return comment
    })
  })
}

// 传入Reply组件
<Reply
  // 其他原有Props不变
  addNestedReply={addNestedReply}
/>
  1. 在Reply组件提交回复成功后,调用该方法传入当前父评论ID和接口返回的新回复数据即可,无需重新拉取全量评论。

功能示意图

功能示意图

内容的提问来源于stack exchange,提问作者sunpl13

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.03 11:18:00