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方式提交表单数据,完成后重定向到当前页面。
原因分析
- 数据获取时机问题:当前组件是异步Server Component,
getPosts仅在组件初始化时执行一次。提交表单后页面重定向,但如果没有触发组件重新渲染或数据重新获取,就无法看到新增内容。 - 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
相关产品推荐
相关产品推荐

