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

NextJS创建新Post后无法显示,如何更新ListOfPosts组件?

解决创建新帖子后列表不更新的问题

问题根源

  1. jsonplaceholder的模拟特性:它的POST请求仅返回模拟数据,不会真正将新帖子存入后端,因此重新调用GET接口也获取不到刚创建的帖子。
  2. 组件状态隔离:NewPost和ListOfPosts的状态各自独立,创建新帖子后没有通知列表组件更新数据。

解决方案

通过状态提升将帖子列表的状态管理移到父组件PostsPage中,让NewPost创建帖子后直接更新父组件的状态,实现列表实时显示新内容。

1. 修改父组件 posts/page.jsx

把帖子状态和初始化获取逻辑移到父组件,同时给子组件传递状态更新的回调和帖子数据:

'use client'
import { useEffect, useState } from "react";
import ListOfPosts from "./ListOfPosts";
import NewPost from "./NewPost";
import axios from "axios";

export default function PostsPage() {
  const [posts, setPosts] = useState([]);

  // 初始化获取帖子列表
  useEffect(() => {
    const fetchPosts = async () => {
      try {
        const response = await axios.get('https://jsonplaceholder.typicode.com/posts');
        setPosts(response.data);
      } catch (error) {
        console.log(error);
      }
    };
    fetchPosts();
  }, []);

  // 处理新帖子创建后的状态更新
  const handlePostCreated = (newPost) => {
    // 将新帖子添加到列表顶部
    setPosts(prevPosts => [newPost, ...prevPosts]);
  };

  return (
    <>
      <section>
        <NewPost onPostCreated={handlePostCreated} />
        <ListOfPosts posts={posts} />
      </section>
    </>
  );
}

2. 修改 NewPost.jsx

让addPost返回模拟的新帖子数据,调用父组件传递的回调通知状态更新:

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

async function addPost(title, body, userId) {
  try {
    const response = await axios.post('https://jsonplaceholder.typicode.com/posts', {
      title,
      body,
      userId,
    });
    return response.data; // 返回模拟的新帖子数据
  } catch (error) {
    console.error('Error creating post:', error);
    return null;
  }
}

function NewPost({ onPostCreated }) {
  const [title, setTitle] = useState('');
  const [body, setBody] = useState('');
  const [userId, setUserId] = useState(1);

  const handleSubmit = async (e) => {
    e.preventDefault();
    const newPost = await addPost(title, body, userId);
    if (newPost) {
      onPostCreated(newPost); // 通知父组件更新列表
    }
    // 重置表单
    setTitle('');
    setBody('');
  };

  return (
    <div>
      <h2>Create New Post</h2>
      <form onSubmit={handleSubmit}>
        <div>
          <label htmlFor="title">Title:</label>
          <input
            name="title"
            type="text"
            id="title"
            value={title}
            onChange={(e) => setTitle(e.target.value)}
            required
            className='text-red-500'
          />
        </div>
        <div>
          <label htmlFor="body">Body:</label>
          <input
            type="text"
            id="body"
            value={body}
            onChange={(e) => setBody(e.target.value)}
            required
            className='text-red-500'
          />
        </div>
        <button type="submit">Create Post</button>
      </form>
    </div>
  );
}

export default NewPost;

3. 修改 ListOfPosts.jsx

不再自行管理状态,直接使用父组件传递的posts数据:

'use client'
import Link from "next/link";

export default function ListOfPosts({ posts }) {
    return posts.map(post => (
        <Link href={`/posts/${post.id}`} key={post.id}>
            <article>
                <h2 style={{color: '#09f'}}>{post.id}  {post.title}</h2>
                <p>{post.body}</p>
            </article>
        </Link>
    ))
}

补充说明

  • 针对jsonplaceholder的模拟特性,我们直接将返回的模拟新帖子添加到前端列表,实现实时显示。
  • 如果是真实后端API,可在handlePostCreated中重新调用fetchPosts函数,从后端拉取最新的帖子列表,确保数据一致性。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 21:32:04