服务器函数
服务器函数允许客户端组件调用在服务器上执行的异步函数。
当使用"use server"
指令定义服务器函数时,您的框架将自动创建对服务器函数的引用,并将该引用传递给客户端组件。当在客户端调用该函数时,React 将向服务器发送请求以执行该函数并返回结果。
服务器函数可以在服务器组件中创建,并作为道具传递给客户端组件,或者可以在客户端组件中导入和使用。
用法
从服务器组件创建服务器函数
服务器组件可以使用"use server"
指令定义服务器函数
// 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
服务器函数时,它将创建对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()}>Create Empty Note</button>
}
更多信息,请参阅"use server"
的文档。
从客户端组件导入服务器函数
客户端组件可以从使用"use server"
指令的文件中导入服务器函数。
"use server";
export async function createNote() {
await db.notes.create();
}
当打包器构建EmptyNote
客户端组件时,它将创建一个指向包中createNoteAction
函数的引用。当单击button
时,React将向服务器发送请求,以使用提供的引用执行createNoteAction
函数。
"use client";
import {createNote} from './actions';
function EmptyNote() {
console.log(createNote);
// {$$typeof: Symbol.for("react.server.reference"), $$id: 'createNoteAction'}
<button onClick={() => createNote()} />
}
更多信息,请参阅"use server"
的文档。
带有 Action 的服务器函数
可以在客户端的 Actions 中调用服务器函数。
"use server";
export async function updateName(name) {
if (!name) {
return {error: 'Name is required'};
}
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);
if (!error) {
setError(error);
} else {
setName('');
}
})
}
return (
<form action={submitAction}>
<input type="text" name="name" disabled={isPending}/>
{state.error && <span>Failed: {state.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
的服务器函数
您可以使用useActionState
调用服务器函数,用于您只需要访问 action 挂起状态和最后返回的响应的常见情况。
"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
与服务器函数一起使用时,React还会自动重播在完成 hydration 之前输入的表单提交。这意味着用户甚至可以在应用程序完成 hydration 之前与您的应用程序进行交互。
更多信息,请参见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
文档。