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

Next.js Server Actions执行后新增数据未显示在数据列表中

问题:createPost添加数据后列表不显示新增内容

我已经成功运行createPost添加函数,但查看数据列表时,之前添加的数据并未显示出来。相关代码如下:

import React, { useEffect, useState } from "react";
import { createPost } from "./actions";
import { SubmitButton } from "./submitButton";
async function getPosts() {
  const res = await fetch("https://dummyjson.com/posts/search?q=&limit=0&skip=0", { cache: 'no-store' });
  const {posts} = await res.json();
  return posts;
}
const FormPost = async ({ params }: { params: { id: string } }) => {
  const data = await getPosts()

  return (
    <>
      <form action={createPost}>
        <input type="text" name="title" className="border" />
        <input type="text" name="body" className="border" />
        <input type="text" name="userId" className="border" />
        <input type="text" name="tags" className="border" />
        <input type="text" name="reactions" className="border" />
        <SubmitButton />
      </form>
      <div className="p-10 flex flex-wrap gap-5">
        {data.map((d: any, index: any) => (
          <div key={index} className="p-1 shadow">
            <p>{d.body.slice(0, 5)}</p>
          </div>
        ))}
      </div>
    </>
  );
};

export default FormPost;

createPost是一个Next.js Server Action,逻辑为:调用https://dummyjson.com/posts/add接口,以POST方式提交表单数据,完成后重定向到当前页面。


原因分析
  1. 数据获取时机问题:当前组件是异步Server Component,getPosts仅在组件初始化时执行一次。提交表单后页面重定向,但如果没有触发组件重新渲染或数据重新获取,就无法看到新增内容。
  2. DummyAPI的模拟特性:https://dummyjson.com是模拟API,其/posts/add接口不会持久化存储新增数据,所有新增内容都是临时的,刷新后会自动消失。

解决方案

一、修复组件数据刷新逻辑

方案1:改用客户端组件,手动更新状态

将组件改为客户端组件,用useState管理数据,提交后主动重新获取数据或直接添加到状态:

'use client';
import React, { useEffect, useState } from "react";
import { createPost } from "./actions";
import { SubmitButton } from "./submitButton";

async function getPosts() {
  const res = await fetch("https://dummyjson.com/posts/search?q=&limit=0&skip=0", { cache: 'no-store' });
  const {posts} = await res.json();
  return posts;
}

const FormPost = ({ params }: { params: { id: string } }) => {
  const [posts, setPosts] = useState<any[]>([]);

  // 初始化获取数据
  useEffect(() => {
    const fetchPosts = async () => {
      const data = await getPosts();
      setPosts(data);
    };
    fetchPosts();
  }, []);

  const handleSubmit = async (e: React.FormEvent) => {
    e.preventDefault();
    const formData = new FormData(e.currentTarget);
    
    // 提交数据
    await createPost(formData);
    
    // 方式A:重新获取完整列表
    const updatedPosts = await getPosts();
    setPosts(updatedPosts);
    
    // 方式B:直接将新增内容添加到现有列表(适合模拟API场景)
    // const newPost = {
    //   title: formData.get('title') as string,
    //   body: formData.get('body') as string,
    //   userId: Number(formData.get('userId')),
    //   tags: (formData.get('tags') as string)?.split(','),
    //   reactions: Number(formData.get('reactions')),
    //   id: Date.now()
    // };
    // setPosts(prev => [...prev, newPost]);
  };

  return (
    <>
      <form onSubmit={handleSubmit}>
        <input type="text" name="title" className="border" />
        <input type="text" name="body" className="border" />
        <input type="text" name="userId" className="border" />
        <input type="text" name="tags" className="border" />
        <input type="text" name="reactions" className="border" />
        <SubmitButton />
      </form>
      <div className="p-10 flex flex-wrap gap-5">
        {posts.map((d: any, index: any) => (
          <div key={index} className="p-1 shadow">
            <p>{d.body.slice(0, 5)}</p>
          </div>
        ))}
      </div>
    </>
  );
};

export default FormPost;

方案2:在Server Action中添加重验证

如果继续使用Server Component,在createPost中调用revalidatePath触发页面重新渲染:

// actions.ts
import { redirect, revalidatePath } from 'next/navigation';

export async function createPost(formData: FormData) {
  await fetch('https://dummyjson.com/posts/add', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({
      title: formData.get('title'),
      body: formData.get('body'),
      userId: Number(formData.get('userId')),
      tags: formData.get('tags')?.split(','),
      reactions: Number(formData.get('reactions'))
    })
  });

  // 重新验证当前页面路径,触发Server Component重新获取数据
  revalidatePath('/your-page-path'); // 替换为实际页面路由
  redirect('/your-page-path');
}

二、解决DummyAPI的临时数据限制

由于dummyjson.com不会持久化数据,若需要长期保存内容,你需要:

  • 替换为真实的后端API(如Node.js + MongoDB、Firebase等)
  • 在前端用本地存储(localStorage)临时保存新增数据,初始化时合并到列表中

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 01:25:02