服务器函数
服务器函数允许客户端组件调用在服务器上执行的异步函数。
🌐 Server Functions allow Client Components to call async functions executed on the server.
当使用 "use server" 指令定义服务器函数时,你的框架会自动创建对该服务器函数的引用,并将该引用传递给客户端组件。当在客户端调用该函数时,React 会向服务器发送请求以执行该函数,并返回结果。
🌐 When a Server Function is defined with the "use server" directive, your framework will automatically create a reference to the Server Function, and pass that reference to the Client Component. When that function is called on the client, React will send a request to the server to execute the function, and return the result.
服务器函数可以在服务器组件中创建并作为属性传递给客户端组件,也可以导入并在客户端组件中使用。
🌐 Server Functions can be created in Server Components and passed as props to Client Components, or they can be imported and used in Client Components.
用法
🌐 Usage
从服务器组件创建服务器函数
🌐 Creating a Server Function from a Server Component
服务器组件可以使用 "use server" 指令定义服务器函数:
🌐 Server Components can define Server Functions with the "use server" directive:
// 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 函数:
🌐 When React renders the EmptyNote Server Component, it will create a reference to the createNoteAction function, and pass that reference to the Button Client Component. When the button is clicked, React will send a request to the server to execute the createNoteAction function with the reference provided:
"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" 的文档。
🌐 For more, see the docs for "use server".
从客户端组件导入服务器函数
🌐 Importing Server Functions from Client Components
客户端组件可以从使用 "use server" 指令的文件中导入服务器函数:
🌐 Client Components can import Server Functions from files that use the "use server" directive:
"use server";
export async function createNote() {
await db.notes.create();
}当打包工具构建 EmptyNote 客户端组件时,它将在包中创建对 createNote 函数的引用。当点击 button 时,React 将向服务器发送请求,以使用提供的引用执行 createNote 函数:
🌐 When the bundler builds the EmptyNote Client Component, it will create a reference to the createNote function in the bundle. When the button is clicked, React will send a request to the server to execute the createNote function using the reference provided:
"use client";
import {createNote} from './actions';
function EmptyNote() {
console.log(createNote);
// {$$typeof: Symbol.for("react.server.reference"), $$id: 'createNote'}
<button onClick={() => createNote()} />
}更多信息,请参阅 "use server" 的文档。
🌐 For more, see the docs for "use server".
带有操作的服务器函数
🌐 Server Functions with Actions
服务器函数可以从客户端上的操作调用:
🌐 Server Functions can be called from Actions on the client:
"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}/>
{error && <span>Failed: {error}</span>}
</form>
)
}这允许你通过在客户端将其封装在一个动作中来访问服务器函数的 isPending 状态。
🌐 This allows you to access the isPending state of the Server Function by wrapping it in an Action on the client.
更多信息,请参阅 在 <form> 之外调用服务器函数 的文档
🌐 For more, see the docs for Calling a Server Function outside of <form>
带有表单操作的服务器函数
🌐 Server Functions with Form Actions
服务器函数可与 React 19 中的新表单功能配合使用。
🌐 Server Functions work with the new Form features in React 19.
你可以将服务器函数传递给表单以自动将表单提交到服务器:
🌐 You can pass a Server Function to a Form to automatically submit the form to the server:
"use client";
import {updateName} from './actions';
function UpdateName() {
return (
<form action={updateName}>
<input type="text" name="name" />
</form>
)
}当表单提交成功时,React 会自动重置表单。你可以添加 useActionState 来访问挂起状态、上一次响应,或支持渐进增强。
🌐 When the Form submission succeeds, React will automatically reset the form. You can add useActionState to access the pending state, last response, or to support progressive enhancement.
更多信息,请参阅 表单中的服务器功能 文档。
🌐 For more, see the docs for Server Functions in Forms.
带有 useActionState 的服务器功能
🌐 Server Functions with useActionState
在常见情况下,如果你只需要访问操作待处理状态和最后返回的响应,可以使用 useActionState 调用服务器函数:
🌐 You can call Server Functions with useActionState for the common case where you just need access to the action pending state and last returned response:
"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 还会自动重新执行在水合完成之前输入的表单提交。这意味着用户即使在应用水合之前也可以与你的应用进行交互。
🌐 When using useActionState with Server Functions, React will also automatically replay form submissions entered before hydration finishes. This means users can interact with your app even before the app has hydrated.
更多信息,请参阅 useActionState 的文档。
🌐 For more, see the docs for useActionState.
useActionState 的渐进增强
🌐 Progressive enhancement with useActionState
服务器功能也支持通过 useActionState 的第三个参数进行渐进增强。
🌐 Server Functions also support progressive enhancement with the third argument of 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 的文档。
🌐 For more, see the docs for useActionState.