YEN HARVEY
cd ../notes

开发日志

为什么我放弃了 Next.js Server Actions

5 min read
夜色中伏案编码的动画风格插画,城市灯光映在窗上。
夜色中伏案编码的动画风格插画,城市灯光映在窗上。

最近在重构一个中型项目时,我把所有的 Next.js Server Actions 都换掉了。这篇记录一下为什么。

一开始很美好

Server Actions 让你能在组件里”直接”调用服务端函数,省去了手写 API route 的样板代码:

async function createPost(formData: FormData) {
	'use server';
	await db.post.create({ title: formData.get('title') });
}

写 demo 的时候确实丝滑。但项目长大以后,问题开始浮现。

真正的痛点

  • 类型边界模糊:客户端和服务端的代码混在一个文件里,重构时很容易把不该泄漏的依赖带到客户端。
  • 错误处理割裂:表单提交失败时的状态管理,比传统的请求-响应模型更难统一。
  • 可测试性下降:把数据访问藏在组件里,单元测试变得别扭。

我现在的做法

退回到清晰的分层:UI 只管渲染,数据访问集中在独立的模块里,边界一目了然。少了一点”魔法”,多了很多确定性。

// 组件里直接调用服务端,边界模糊
async function createPost(formData: FormData) {
	'use server';
	await db.post.create({ title: formData.get('title') });
}
// 数据访问集中在独立模块,边界清晰
// lib/posts.ts
export async function createPost(input: PostInput) {
	return db.post.create({ data: input });
}

工具的便利,不该以牺牲架构的清晰为代价。

作者头像
yen@harvey:~$ exit 0