·
Next.jsServer Actions全栈
Next.js Server Actions 实战:从表单到可维护工作流
用一个“评论发布”场景串起 Server Actions 的核心用法,覆盖表单提交、输入校验、错误处理、重定向和缓存刷新,给出可直接落地的工程实践。
渲染风格:
为什么要用 Server Actions
在 App Router 中,Server Actions 让“前端表单 + 后端写入”这条链路变得更短:你不一定要先写一层 API route,再在客户端发请求。
它的价值不是“少写代码”这么简单,而是:
- 把数据写操作放在服务端边界内,减少敏感逻辑泄露风险;
- 更自然地配合缓存策略,提交后可以直接触发数据刷新;
- 让组件和数据操作更贴近业务语义,降低维护成本。
一个最小可用示例
先定义服务端 action:
"use server";
import { revalidatePath } from "next/cache";
export async function createComment(formData: FormData) {
const postId = String(formData.get("postId") ?? "");
const content = String(formData.get("content") ?? "").trim();
if (!postId || content.length < 3) {
return { ok: false, message: "评论至少 3 个字" };
}
// 这里替换成真实数据库写入
await Promise.resolve({ postId, content });
revalidatePath(`/blog/${postId}`);
return { ok: true };
}
再在页面中使用表单提交:
import { createComment } from "./actions";
export default function CommentForm({ postId }: { postId: string }) {
return (
<form action={createComment} className="space-y-3">
<input type="hidden" name="postId" value={postId} />
<textarea name="content" placeholder="写下你的评论..." />
<button type="submit">发布评论</button>
</form>
);
}
生产环境建议
1. 输入校验要双层
前端校验负责体验,服务端校验负责安全。不要只依赖浏览器约束。
2. 对错误做可预期建模
建议把返回结果统一为:
type ActionResult = { ok: true } | { ok: false; message: string };
这样 UI 能稳定消费,不会在异常分支写大量 any。
3. 缓存刷新按范围最小化
revalidatePath 很方便,但范围越大成本越高。尽量只刷新受影响的页面或列表,不要无脑刷新全站。
4. 权限在 action 内兜底
即使按钮只对登录用户可见,也要在 action 内校验用户身份与资源归属,这是最后一道防线。
什么时候不该用
如果你的场景是“多端统一消费 API(Web + App + 第三方)”,那仍然建议抽 API 层。Server Actions 更适合“Web 站点内聚业务”。
小结
Server Actions 不是为了替代所有接口,而是帮我们在合适场景里用更低认知负担交付业务。关键不在于语法,而在于边界:把校验、权限、缓存策略一起设计,才能真正可维护。