Server Functions
Server Functions allow Client Components to call async functions executed on the server.
When a Server Functions 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
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}/>;
}
When React renders the EmptyNote
Server Function, 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>
}
For more, see the docs for "use server"
.
Importing Server Functions from Client Components
Client Components can import Server Functions from files that use the "use server"
directive:
"use server";
export async function createNote() {
await db.notes.create();
}
When the bundler builds the EmptyNote
Client Component, it will create a reference to the createNoteAction
function in the bundle. When the button
is clicked, React will send a request to the server to execute the createNoteAction
function using the reference provided:
"use client";
import {createNote} from './actions';
function EmptyNote() {
console.log(createNote);
// {$$typeof: Symbol.for("react.server.reference"), $$id: 'createNoteAction'}
<button onClick={() => createNote()} />
}
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}/>
{state.error && <span>Failed: {state.error}</span>}
</form>
)
}
This allows you to access the isPending
state of the Server Function by wrapping it in an Action on the client.
For more, see the docs for Calling a Server Function outside of <form>
Server Functions with Form Actions
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>
)
}
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.
Server Functions with 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>
);
}
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.
For more, see the docs for useActionState
.
Progressive enhancement with 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>
);
}
When the permalink is provided to useActionState
, React will redirect to the provided URL if the form is submitted before the JavaScript bundle loads.
For more, see the docs for useActionState
.