Next.js 现在允许开发者直接从组件中调用仅限服务器(server-only)的函数,从而消除了为表单提交等日常任务创建独立 API 路由的需求。通过使用全新的 Server Actions 功能,单个 HTML 表单即可触发后端代码,无需中间的 fetch 调用,从而减少了样板代码并强化了前后端契约。

为什么传统方式显得繁重

在典型的 React 或 Next.js 应用中,一个简单的“创建项目”表单会触发一系列步骤:一个 API 路由文件、来自浏览器的 fetch 请求、加载和错误状态的处理、CORS 标头,最后是反映新数据的客户端更新。每一步都会增加文件、代码行数和故障点。即使目标仅仅是将一条记录写入数据库,团队仍需花费时间将这些环节连接起来。

Server Actions 弥合了差距

Server Actions 是保证仅在服务器上运行的异步函数。在文件顶部添加 "use server" 指令会告知编译器将代码排除在浏览器包之外,因此它可以安全地访问数据库、密钥或任何仅限服务器的资源。由于该函数存在于服务器端,组件可以通过原生 <form> 元素的 action 属性直接调用它。

定义一个 action

export async function createProject(formData: FormData) {
  const title = formData.get('title') as string;

  if (!title) throw new Error('Title is required');

  await db.project.create({
    data: { title }
  });

  revalidatePath('/dashboard');
}

该函数接收一个 FormData 对象,验证有效载荷(payload),写入数据库,然后请求 Next.js 刷新 /dashboard 页面,以便 UI 在无需完整重新加载的情况下显示新项目。

在 UI 中进行挂载

export default function NewProjectForm() {
  return (
    <form action={createProject}>
      <input type="text" name="title" required />
      <SubmitButton />
    </form>
  );
}

当用户点击提交按钮时,浏览器会将表单数据 POST 到服务器端的 createProject 函数。由于这使用了标准的 HTML 表单行为,即使 JavaScript 尚未加载,提交操作仍然有效,从而提高了在慢速连接上的感知性能。

团队能获得什么

  • 更少的文件 – 每个端点不再需要独立的 pages/apiapp/api 文件。
  • 更少的连接工作 – 无需手动调用 fetch,无需显式处理 CORS。
  • 内置类型安全 – 函数签名在服务器和客户端之间共享,因此 TypeScript 可以及早发现不匹配。
  • 性能优势 – 请求直接传输到服务器函数,绕过了客户端 fetch 会引入的额外网络跳转。

限制与注意事项

Server Actions 仍处于早期阶段。它们只能是标记为 "use server" 的异步函数,且不能向客户端返回任意 JavaScript 对象;它们必须以重定向(redirect)、重新验证(revalidation)或普通响应(plain response)结束。由于调用栈会从浏览器跳转到服务器运行时,调试体验可能会有所不同,这可能会让习惯于传统 API 路由日志的开发者感到意外。此外,涉及多个微服务或需要精细 HTTP 状态码的复杂工作流可能仍需要传统的 API 端点。

需要关注的事项

Next.js 可能会在未来的版本中扩展 Server Actions API,增加对更多响应类型的支持以及更好的工具集成。早期采用者应密切关注框架的变更日志(changelog)和社区反馈,以便在将关键任务功能迁移到此路径之前评估其稳定性。监控包大小(bundle size)和服务器渲染指标也可以揭示减少后的客户端代码是否能为您的特定流量模式带来可衡量的延迟收益。

总结

通过允许组件直接调用仅限服务器的函数,Next.js Server Actions 消除了长期以来充斥在 React 项目中的中间环节。其结果是更简洁的代码、更快的往返速度以及更流畅的开发体验——前提是该功能的当前约束符合项目的需求。