
服务器函数
title: 服务器函数
Server Functions 用于 React Server Components。
注意: 在 2024 年 9 月之前,我们将所有 Server Functions 称为 "Server Actions"。如果某个 Server Function 被传递给 action prop 或在 action 内部被调用,那么它就是 Server Action,但并非所有 Server Functions 都是 Server Actions。本文档中的命名已更新,以反映 Server Functions 可用于多种用途。
Server Functions 允许 Client Components 调用在服务器上执行的异步函数。
目录
如何构建对 Server Functions 的支持?
虽然 React 19 中的 Server Functions 是稳定的,不会在次要版本之间发生破坏性变更,但用于在 React Server Components 打包器或框架中实现 Server Functions 的底层 API 不遵循 semver,可能在 React 19.x 的次要版本之间发生破坏性变更。
要作为打包器或框架支持 Server Functions,我们建议锁定特定的 React 版本,或使用 Canary 版本。我们将继续与打包器和框架合作,以在未来稳定用于实现 Server Functions 的 API。
当 Server Function 使用 "use server" 指令定义时,你的框架会自动创建对该 Server Function 的引用,并将该引用传递给 Client Component。当客户端调用该函数时,React 会向服务器发送请求以执行该函数,并返回结果。
Server Functions 可以在 Server Components 中创建,并作为 props 传递给 Client Components;也可以在 Client Components 中导入和使用。
用法
从 Server Component 创建 Server Function
Server Components 可以使用 "use server" 指令定义 Server Functions:
js [[2, 7, "'use server'"], [1, 5, "createNoteAction"], [1, 12, "createNoteAction"]]
// Server Component
import Button from './Button';
function EmptyNote () {
async function createNoteAction() {
// Server Function
'use server';
await db.notes.create();
}
return <Button onClick={createNoteAction}/>;
}
当 React 渲染 EmptyNote Server Component 时,它会创建对 createNoteAction 函数的引用,并将该引用传递给 Button Client Component。当按钮被点击时,React 会使用提供的引用向服务器发送请求,以执行 createNoteAction 函数:
js {5}
"use client";
export default function Button({onClick}) {
console.log(onClick);
// {$$typeof: Symbol.for("react.server.reference"), $$id: 'createNoteAction'}
return <button onClick={() => onClick()}>Create Empty Note</button>
}
更多信息,请参阅 "use server" 的文档。
从 Client Components 导入 Server Functions
Client Components 可以从使用 "use server" 指令的文件中导入 Server Functions:
js [[1, 3, "createNote"]]
"use server";
export async function createNote() {
await db.notes.create();
}
当打包器构建 EmptyNote Client Component 时,它会在 bundle 中创建对 createNote 函数的引用。当 button 被点击时,React 会使用提供的引用向服务器发送请求,以执行 createNote 函数:
js [[1, 2, "createNote"], [1, 5, "createNote"], [1, 7, "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" 的文档。
将 Server Functions 与 Actions 一起使用
Server Functions 可以从客户端的 Actions 中调用:
js [[1, 3, "updateName"]]
"use server";
export async function updateName(name) {
if (!name) {
return {error: 'Name is required'};
}
await db.users.updateName(name);
}
js [[1, 3, "updateName"], [1, 13, "updateName"], [2, 11, "submitAction"], [2, 23, "submitAction"]]
"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);
if (error) {
setError(error);
} else {
setName('');
}
})
}
return (
<form action={submitAction}>
<input type="text" name="name" disabled={isPending}/>
{error && <span>Failed: {error}</span>}
</form>
)
}
这样,你可以通过在客户端将 Server Function 包装在 Action 中来访问其 isPending 状态。
更多信息,请参阅 在 <form> 之外调用 Server Function 的文档。
将 Server Functions 与 Form Actions 一起使用
Server Functions 可以与 React 19 中新的 Form 特性一起使用。
你可以将 Server Function 传递给 Form,以自动将表单提交到服务器:
js [[1, 3, "updateName"], [1, 7, "updateName"]]
"use client";
import {updateName} from './actions';
function UpdateName() {
return (
<form action={updateName}>
<input type="text" name="name" />
</form>
)
}
当 Form 提交成功时,React 会自动重置表单。你可以添加 useActionState 来访问 pending 状态、上一次响应,或支持渐进增强。
更多信息,请参阅 Forms 中的 Server Functions 的文档。
将 Server Functions 与 useActionState 一起使用
对于你只需要访问 action 的 pending 状态和最后一次返回的响应的常见场景,你可以将 Server Functions 与 useActionState 一起使用:
js [[1, 3, "updateName"], [1, 6, "updateName"], [2, 6, "submitAction"], [2, 9, "submitAction"]]
"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>Failed: {state.error}</span>}
</form>
);
}
当将 useActionState 与 Server Functions 一起使用时,React 还会自动重放 hydration 完成之前输入的表单提交。这意味着即使在应用完成 hydration 之前,用户也可以与应用交互。
更多信息,请参阅 useActionState 的文档。
使用 useActionState 进行渐进增强
Server Functions 还通过 useActionState 的第三个参数支持渐进增强。
js [[1, 3, "updateName"], [1, 6, "updateName"], [2, 6, "/name/update"], [3, 6, "submitAction"], [3, 9, "submitAction"]]
"use client";
import {updateName} from './actions';
function UpdateName() {
const [, submitAction] = useActionState(updateName, null, `/name/update`);
return (
<form action={submitAction}>
...
</form>
);
}
当向 useActionState 提供 permalink 时,如果表单在 JavaScript bundle 加载之前提交,React 会重定向到所提供的 URL。
更多信息,请参阅 useActionState 的文档。
帮助我们改进文档
发现翻译问题或内容错误?请告诉我们。
