Server Functions definition and purpose
Server Functions are async functions executed on the server that can be called from Client Components. They allow Client Components to call server-side logic. Server Functions are defined with the 'use server' directive.
Server Actions vs Server Functions naming distinction
Server Functions is the umbrella term for all functions marked with 'use server'. A Server Function becomes a Server Action specifically when it is passed to an action prop or called from inside an action. Not all Server Functions are Server Actions.
Server Function reference object structure
When a Server Function is passed to a Client Component, it becomes a reference object with the structure: {$$typeof: Symbol.for('react.server.reference'), $$id: 'functionName'}. This reference is what enables React to send requests to the server.
Creating Server Functions in Server Components
Server Components can define Server Functions inline using the 'use server' directive inside an async function. These functions are automatically converted to references and passed as props to Client Components.
Importing Server Functions in Client Components
Client Components can import Server Functions from files that start with the 'use server' directive at the top. The imported functions are converted to references by the bundler, allowing them to be called from the client.
Server Functions with useTransition for manual actions
Server Functions can be called within useTransition to access isPending state. Wrap the Server Function call in startTransition to track the loading state of the server operation manually.
Server Functions with form action prop
Server Functions can be passed directly to the action prop of a form element. React will automatically submit the form to the server when submitted, and automatically reset the form on success.
Server Functions with useActionState basic usage
useActionState accepts a Server Function as its first argument and an initial state as its second argument. It returns [state, submitAction, isPending] to access the pending state and last response from the Server Function.
Server Functions with useActionState progressive enhancement
useActionState accepts a third argument which is a permalink URL. When provided, React redirects to this URL if the form is submitted before the JavaScript bundle loads, enabling progressive enhancement.
Server Functions automatic form replay before hydration
When using useActionState with Server Functions, React automatically replays form submissions that were entered before hydration completes. This allows users to interact with the app and have their actions preserved before JavaScript loads.
Server Functions can return error objects
Server Functions can return response objects, such as {error: 'message'}, which are sent back to the client. The client can check these response objects to handle errors or display status information.
Creating Server Function from Server Component example
Example showing Server Function creation in a Server Component:
```js
// Server Component
import Button from './Button';
function EmptyNote () {
async function createNoteAction() {
// Server Function
'use server';
await db.notes.create();
}
return <Button onClick={createNoteAction}/>;
}
```
Importing and using Server Function in Client Component example
Example showing Server Function import in a Client Component:
```js
"use client";
import {createNote} from './actions';
function EmptyNote() {
console.log(createNote);
// {$$typeof: Symbol.for('react.server.reference'), $$id: 'createNote'}
<button onClick={() => createNote()} />
}
```
Server Function with useTransition example
Example showing Server Function called within useTransition for pending state:
```js
"use client";
import {updateName} from './actions';
import {useTransition, useState} from 'react';
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);
startTransition(() => {
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 with form action prop example
Example showing Server Function passed directly to form action prop:
```js
"use client";
import {updateName} from './actions';
function UpdateName() {
return (
<form action={updateName}>
<input type="text" name="name" />
</form>
)
}
```
Server Function with useActionState example
Example showing Server Function with useActionState:
```js
"use client";
import {updateName} from './actions';
import {useActionState} from 'react';
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>
);
}
```
Server Function with useActionState progressive enhancement example
Example showing Server Function with useActionState using progressive enhancement permalink:
```js
"use client";
import {updateName} from './actions';
import {useActionState} from 'react';
function UpdateName() {
const [, submitAction] = useActionState(updateName, null, `/name/update`);
return (
<form action={submitAction}>
...
</form>
);
}
```
'use server' directive marks server-side functions callable from client code
The 'use server' directive marks async functions as Server Functions that can be called from client-side code. When a Server Function is called from the client, it makes a network request to the server with serialized arguments, and the return value is serialized and returned to the client.
'use server' placement rules
'use server' must be at the very beginning of a function body or at the top of a module file, above any other code including imports. Comments above the directive are allowed. It must be written with single or double quotes, not backticks.
'use server' file-level usage
Instead of marking individual functions with 'use server', you can add the directive at the top of a file to mark all exports within that file as Server Functions that can be used anywhere, including imported in client code.
'use server' must be used on async functions only
Because the underlying network calls are always asynchronous, 'use server' can only be used on async functions.
'use server' can only be used in server-side files
'use server' can only be used in server-side files. The resulting Server Functions can be passed to Client Components through props. To import a Server Function from client code, the directive must be used at module level.
Server Functions should be called in transitions
Server Functions should be called in a Transition using useTransition. Server Functions passed to form action or formAction will automatically be called in a transition. Server Functions are designed for mutations that update server-side state, not for data fetching.
'use server' serializable parameters and return values
Serializable types for Server Function arguments and return values include: Primitives (string, number, bigint, boolean, undefined, null, symbol via Symbol.for), Iterables (String, Array, Map, Set, TypedArray, ArrayBuffer), Date, FormData instances, plain objects with serializable properties, Server Functions, and Promises. Not supported: React elements/JSX, non-Server Functions, Classes, class instances (except built-ins), symbols not registered globally, and event handler events. Supported return values are the same as serializable props for Client Components.
'use server' security considerations
Server Function arguments are fully client-controlled and must be treated as untrusted input. Always validate and escape arguments as appropriate. Validate that the logged-in user is authorized to perform each action. Experimental taint APIs (experimental_taintUniqueValue and experimental_taintObjectReference) can prevent sensitive data from being passed to client code.
Server Function in form action example
async function requestUsername(formData) {
'use server';
const username = formData.get('username');
// ...
}
export default function App() {
return (
<form action={requestUsername}>
<input type="text" name="username" />
<button type="submit">Request</button>
</form>
);
}
This example shows a Server Function passed to form action. React supplies the form's FormData as the first argument.
Server Function return value handling with useActionState
'use client';
import { useActionState } from 'react';
import requestUsername from './requestUsername';
function UsernameForm() {
const [state, action] = useActionState(requestUsername, null, 'n/a');
return (
<>
<form action={action}>
<input type="text" name="username" />
<button type="submit">Request</button>
</form>
<p>Last submission request returned: {state}</p>
</>
);
}
This example shows using useActionState to handle the return value of a Server Function while supporting progressive enhancement.
Server Function called outside form with useTransition
import incrementLike from './actions';
import { useState, useTransition } from 'react';
function LikeButton() {
const [isPending, startTransition] = useTransition();
const [likeCount, setLikeCount] = useState(0);
const onClick = () => {
startTransition(async () => {
const currentCount = await incrementLike();
startTransition(() => {
setLikeCount(currentCount);
});
});
};
return (
<>
<p>Total Likes: {likeCount}</p>
<button onClick={onClick} disabled={isPending}>Like</button>
</>
);
}
This example shows calling a Server Function outside a form using useTransition, allowing you to handle the return value and display loading states.
Server Functions support progressive enhancement
By passing a Server Function to the form action prop, React can progressively enhance the form. This means forms can be submitted before the JavaScript bundle is loaded.
Awaiting Server Function return values
To read a Server Function return value, you need to await the promise returned by the Server Function call.