伺服器函式
伺服器函式允許客戶端元件呼叫在伺服器上執行的非同步函式。
當使用 "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"
的文件。
具有動作的伺服器函式
可以從客戶端上的動作呼叫伺服器函式
"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>
之外呼叫伺服器函式 的文件。
具有表單動作的伺服器函式
伺服器函式可與 React 19 中新的表單功能搭配使用。
您可以將伺服器函式傳遞給表單,以自動將表單提交到伺服器。
"use client";
import {updateName} from './actions';
function UpdateName() {
return (
<form action={updateName}>
<input type="text" name="name" />
</form>
)
}
當表單提交成功時,React 會自動重設表單。您可以新增 useActionState
來訪問處理中狀態、最後的回應,或支援漸進式增強。
更多資訊,請參閱關於 表單中的伺服器函式 的文件。
使用 useActionState
的伺服器函式
在只需要訪問動作處理中狀態和最後返回的回應的常見情況下,您可以使用 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>Failed: {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 將會重新導向到提供的網址。
更多資訊,請參閱關於 useActionState
的文件。