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

React中表单提交后如何无需刷新页面渲染新帖子?

解决React提交帖子后无需刷新页面显示新内容的问题

问题原因

PostList组件仅在挂载阶段通过useEffect(() => {fetchPosts()}, [])调用一次fetchPosts获取帖子数据,后续PostCreate提交新帖子后,PostList没有触发重新获取数据的逻辑,所以新帖子不会自动显示。

解决方案

方案1:状态提升(推荐)

将帖子数据的状态管理提升到父组件App中,让PostCreate提交成功后通知App重新获取数据,再把最新数据传递给PostList。

修改后的App.js代码:

const App = () => {
  const [posts, setPosts] = useState({});

  const fetchPosts = async () => {
    try {
      const response = await axios.get(`http://${queries_host}/posts`);
      setPosts(response.data);
    } catch (error) {
      console.log(error);
    }
  };

  // 组件挂载时获取初始数据
  useEffect(() => {
    fetchPosts();
  }, []);

  return (
    <div>
      <h1>Create Post</h1>
      <PostCreate onPostCreated={fetchPosts} />
      <hr/>
      <h1>Posts</h1>
      <PostList posts={posts} />
    </div>
  );
};
export default App;

修改后的PostCreate组件:

const PostCreate = ({ onPostCreated }) => {
  const [title, setTitle] = useState('');
  const onSubmit = async (event) => {
    event.preventDefault();
    try {
      await axios.post(`http://${posts_host}/posts/create`, { title });
      setTitle('');
      // 提交成功后通知父组件重新获取帖子
      onPostCreated();
    } catch (error) {
      console.log(error);
    }
  };

  return (
    <div>
      <form onSubmit={onSubmit}>
        <div className="form-group">
          <label>Title</label>
          <input 
            value={title} 
            onChange={event => setTitle(event.target.value)}
            className="form-control"
          />
        </div>
        <button className="btn btn-primary">Submit</button>
      </form>
    </div>
  )
}
export default PostCreate;

修改后的PostList组件:

const PostList = ({ posts }) => {
  const renderedPosts = Object.values(posts).map(post => {
    return (
      <div className="card"
           style={{width: '30%', marginBottom: '20px'}}
           key={post.id}>
        <div className="card-body">
          <h3>{post.title}</h3>
          <CommentList comments={post.comments}></CommentList>
          <CommentCreate postId={post.id}></CommentCreate>
        </div>
      </div>
    );
  });

  return (
    <div>
      {renderedPosts}
    </div>
  );
}
export default PostList;

方案2:使用自定义事件

如果不想提升状态,可以通过自定义事件实现组件间通信:

修改PostCreate组件:

const PostCreate = () => {
  const [title, setTitle] = useState('');
  const onSubmit = async (event) => {
    event.preventDefault();
    try {
      await axios.post(`http://${posts_host}/posts/create`, { title });
      setTitle('');
      // 触发自定义事件
      window.dispatchEvent(new CustomEvent('postCreated'));
    } catch (error) {
      console.log(error);
    }
  };

  return (
    <div>
      <form onSubmit={onSubmit}>
        <div className="form-group">
          <label>Title</label>
          <input 
            value={title} 
            onChange={event => setTitle(event.target.value)}
            className="form-control"
          />
        </div>
        <button className="btn btn-primary">Submit</button>
      </form>
    </div>
  )
}
export default PostCreate;

修改PostList组件:

const PostList = () => {
  const [posts, setPosts] = useState({});
  const fetchPosts = async () => {
    try {
      const response = await axios.get(`http://${queries_host}/posts`);
      setPosts(response.data);
    } catch (error) {
      console.log(error);
    }
  };

  useEffect(() => {
    fetchPosts();
    // 监听自定义事件
    const handlePostCreated = () => fetchPosts();
    window.addEventListener('postCreated', handlePostCreated);
    // 组件卸载时移除监听
    return () => window.removeEventListener('postCreated', handlePostCreated);
  }, []);

  const renderedPosts = Object.values(posts).map(post => {
    return (
      <div className="card"
           style={{width: '30%', marginBottom: '20px'}}
           key={post.id}>
        <div className="card-body">
          <h3>{post.title}</h3>
          <CommentList comments={post.comments}></CommentList>
          <CommentCreate postId={post.id}></CommentCreate>
        </div>
      </div>
    );
  });

  return (
    <div>
      {renderedPosts}
    </div>
  );
}
export default PostList;

内容的提问来源于stack exchange,提问作者watch-this

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 16:01:17