React 官方把 'use server' 这类函数叫 Server Functions。
Next.js 生态里大家更常把它叫 Server Actions。
本章为了贴近 Next.js 社区习惯,继续用“Server Actions”这个叫法。
#1. 最符合 Next.js 心智的写法:表单直接提交到服务端函数
// app/products/actions.ts
'use server';
import { revalidatePath } from 'next/cache';
import { redirect } from 'next/navigation';
export async function createProduct(formData: FormData) {
const name = String(formData.get('name') ?? '').trim();
if (!name) {
throw new Error('商品名不能为空');
}
// await db.product.create({ data: { name } });
revalidatePath('/products');
redirect('/products');
}// app/products/new/page.tsx
import { createProduct } from '../actions';
export default function NewProductPage() {
return (
<form action={createProduct}>
<input name="name" placeholder="商品名" />
<button type="submit">创建商品</button>
</form>
);
}这条链路非常像真实商业系统:
顾客/运营人员填写表单
↓
表单直接提交给服务端动作
↓
服务端写数据库
↓
让商品列表失效重算
↓
跳回最新页面#2. 什么时候它比前端 fetch 更自然?
当你的场景是:
- 表单提交
- CRUD 写入
- 页面提交后刷新结果
- 要和缓存失效联动
这时候 Server Actions 非常顺手。
#3. 前台要即时反馈时,再加 Client 侧增强
比如禁用按钮、显示 pending、显示表单错误,这时你可以在 Client Component 里配合 React 的表单状态 Hook 做增强。
'use client';
import { useActionState } from 'react';
import { createProduct } from '../actions';
const initialState = { message: '' };
export default function ProductForm() {
const [state, formAction, pending] = useActionState(createProduct, initialState);
return (
<form action={formAction}>
<input name="name" placeholder="商品名" />
<button disabled={pending}>
{pending ? '提交中...' : '创建商品'}
</button>
<p>{state.message}</p>
</form>
);
}你可以把它理解成:
- Server Action 负责真的改系统
- Client Component 负责把“正在提交”“提交失败”“乐观反馈”这些交互体验补齐