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

React Hooks实现新增评论后组件无刷新更新方案问询

嘿,我来帮你搞定这个评论提交后自动刷新又不触发无限循环的问题!核心思路是不要依赖useEffect的自动触发,而是在评论提交成功后主动调用数据更新函数,这样既能实现评论实时显示,又不会陷入无限循环的坑。

解决方案步骤

  1. 提取重复调用的获取数据函数:把Page组件里获取帖子和评论的axios请求封装成一个独立函数,方便后续重复调用;
  2. 将更新函数传递给子组件:把这个获取数据的函数传给CreateComment组件,让它在评论提交成功后触发更新;
  3. 仅在组件挂载时初始化数据:保持useEffect的空依赖数组,只在页面加载时获取一次初始数据,避免无意义的重复请求。

修改后的代码示例

Page.js 调整后的代码

import React, { useState, useEffect } from 'react';
import { useParams } from 'react-router-dom';
import axios from 'axios';
import '../CSS/Page.css';
import CreateComment from './CreateComment';

const Page = () => {
  const [show, setShow] = useState({ commentBox: false });
  const [post, setPost] = useState({
    id: '',
    username: '',
    title: '',
    body: '',
    date: '',
    comments: [{}]
  });
  let { postTitle } = useParams();

  // 封装获取帖子数据的函数
  const fetchPost = async () => {
    try {
      const res = await axios.get(
        `http://localhost:2000/apiEndpoint/singlePost/${postTitle}`,
        {
          withCredentials: true,
          headers: { 'Content-Type': 'application/json' }
        }
      );
      // 直接赋值完整的post对象,简化代码
      setPost(res.data);
    } catch (err) {
      console.error('获取帖子数据失败:', err);
    }
  };

  // 组件挂载时初始化数据
  useEffect(() => {
    fetchPost();
  }, []); // 空依赖数组,仅执行一次

  const handleCommentButton = (e) => {
    setShow({ ...show, commentBox: !show.commentBox });
  };

  return (
    <div className='postContainer'>
      <div className='singlePostcontainer'>
        <div className='singlePost'>
          <h1>{post.title}</h1>
          <hr />
          <p>{post.body}</p>
          {post.id}
          <hr />
          <h5>
            Comments:
            <button className='btnCom' onClick={handleCommentButton}>
              {show.commentBox ? 'Close' : 'Add Comment'}
            </button>
          </h5>
          {/* 将更新函数传递给CreateComment组件 */}
          {show.commentBox ? (
            <CreateComment post={post} onCommentSubmit={fetchPost} />
          ) : (
            ''
          )}
          {post.comments.map((comment) => {
            const commentID = comment._id;
            return (
              <div className='comment' key={commentID}>
                <h3>{comment.body}</h3>
                <h6>By: {comment.creater}</h6>
              </div>
            );
          })}
        </div>
      </div>
    </div>
  );
};

export default Page;

CreateComment.js 调整后的代码

import React, { useState } from 'react';
import axios from 'axios';

const CreateComment = (props) => {
  const [comment, setComment] = useState({ body: '' });

  const handleSubmitA = (e) => {
    e.preventDefault();
    axios
      .post(
        `http://localhost:2000/apiEndpoint/CREATE/comment/${props.post.id}`,
        { body: comment.body },
        {
          withCredentials: true,
          headers: { 'Content-Type': 'application/json' }
        }
      )
      .then((res) => {
        console.log('评论提交成功:', res);
        // 触发父组件的数据更新
        props.onCommentSubmit();
        // 清空评论输入框,提升用户体验
        setComment({ body: '' });
      })
      .catch((err) => {
        console.error('评论提交失败:', err);
      });
  };

  const handleChangeA = (e) => {
    const { name, value } = e.target;
    setComment({ ...comment, [name]: value });
  };

  return (
    <div className='commentContainer'>
      <form onSubmit={handleSubmitA}>
        <label>Enter Comment</label>
        <textarea
          name="body"
          value={comment.body}
          onChange={handleChangeA}
        ></textarea>
        <button>Submit</button>
      </form>
    </div>
  );
};

export default CreateComment;

为什么这个方案能解决问题?

  • 原来的无限循环是因为如果把post放进useEffect的依赖数组,每次setPost都会触发useEffect重新请求数据,进而再次setPost,形成闭环;
  • 现在我们只在组件挂载时和评论提交成功时主动调用fetchPost,完全由业务逻辑触发更新,不会产生无意义的重复请求,自然也就避免了无限循环。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.09 15:27:56