服务器函数
服务器函数允许客户端组件调用在服务器上执行的异步函数。
当一个服务器函数使用 "use server" 指令定义时,你的框架会自动创建该服务器函数的引用,并将该引用传递给客户端组件。当该函数在客户端被调用时,React 会向服务器发送请求以执行该函数,并返回结果。
服务器函数可以在服务器组件中创建并作为属性传递给客户端组件,也可以被导入并在客户端组件中使用。
用法
从服务器组件创建服务器函数
服务器组件可以使用 "use server" 指令定义服务器函数:
// 服务器组件
import Button from './Button';
function EmptyNote () {
async function createNoteAction() {
// 服务器函数
'use server';
await db.notes.create();
}
return <Button onClick={createNoteAction}/>;
}当 React 渲染 EmptyNote 服务器组件时,它会创建 createNoteAction 函数的引用,并将该引用传递给 Button 客户端组件。点击按钮时,React 会向服务器发送请求,使用提供的引用执行 createNoteAction 函数:
"use client";
export default function Button({onClick}) {
console.log(onClick);
// {$$typeof: Symbol.for("react.server.reference"), $$id: 'createNoteAction'}
return <button onClick={() => onClick()}>创建空笔记</button>
}更多内容请参阅 "use server" 文档。
从客户端组件导入服务器函数
客户端组件可以从使用 "use server" 指令的文件中导入服务器函数:
"use server";
export async function createNote() {
await db.notes.create();
}当打包工具构建 EmptyNote 客户端组件时,它会在包中为 createNote 函数创建一个引用。点击 button 时,React 会使用提供的引用向服务器发送请求,以执行 createNote 函数:
"use client";
import {createNote} from './actions';
function EmptyNote() {
console.log(createNote);
// {$$typeof: Symbol.for("react.server.reference"), $$id: 'createNote'}
<button onClick={() => createNote()} />
}更多内容请参阅 "use server" 文档。
带有 Actions 的服务器函数
服务器函数可以在客户端的 Actions 中被调用:
"use server";
export async function updateName(name) {
if (!name) {
return {error: '需要姓名'};
}
await db.users.updateName(name);
}"use client";
import {updateName} from './actions';
function UpdateName() {
const [name, setName] = useState('');
const [error, setError] = useState(null);
const [isPending, startTransition] = useTransition();
const submitAction = async () => {
startTransition(async () => {
const {error} = await updateName(name);
startTransition(() => {
if (error) {
setError(error);
} else {
setName('');
}
});
})
}
return (
<form action={submitAction}>
<input type="text" name="name" disabled={isPending}/>
{error && <span>失败:{error}</span>}
</form>
)
}这使你可以通过在客户端将其包装在一个 Action 中,来访问服务器函数的 isPending 状态。
更多内容请参阅在 <form> 外调用服务器函数 文档
带有表单 Actions 的服务器函数
服务器函数可与 React 19 中新的表单特性配合使用。
你可以将服务器函数传递给表单,以自动将表单提交到服务器:
"use client";
import {updateName} from './actions';
function UpdateName() {
return (
<form action={updateName}>
<input type="text" name="name" />
</form>
)
}当表单提交成功时,React 会自动重置表单。你可以添加 useActionState 来访问待处理状态、最后一次响应,或支持渐进增强。
更多内容请参阅表单中的服务器函数 文档。
与 useActionState 配合使用的服务器函数
对于只需要访问 action 的待处理状态和最后返回响应的常见场景,你可以使用 useActionState 调用服务器函数:
"use client";
import {updateName} from './actions';
function UpdateName() {
const [state, submitAction, isPending] = useActionState(updateName, {error: null});
return (
<form action={submitAction}>
<input type="text" name="name" disabled={isPending}/>
{state.error && <span>失败:{state.error}</span>}
</form>
);
}在将 useActionState 与服务器函数一起使用时,React 还会自动回放在水合完成前提交的表单。这意味着用户甚至可以在应用完成水合之前与你的应用交互。
更多内容请参阅 useActionState 文档。
使用 useActionState 的渐进增强
服务器函数也支持通过 useActionState 的第三个参数实现渐进增强。
"use client";
import {updateName} from './actions';
function UpdateName() {
const [, submitAction] = useActionState(updateName, null, `/name/update`);
return (
<form action={submitAction}>
...
</form>
);
}当将 永久链接 提供给 useActionState 时,如果表单在 JavaScript 包加载前就被提交,React 会重定向到提供的 URL。
更多内容请参阅 useActionState 文档。