Check with the server
Whether a username is already taken is something only the server knows. Telling the person when they leave the field, rather than after they submit, saves them a round of fixing. useAsyncCheck attaches that question to one field.
On this page
Attach a check to a field
Pass useAsyncCheck a function that takes the value and resolves to a message, or to undefined when the value is fine. Spread the props it returns onto the field, next to input.
actions.ts'use server';
export async function checkHandle(handle: string) {
return (await handleExists(handle))
? 'This username is already taken'
: undefined;
}signup-form.tsxconst handle = form.field('handle');
const taken = useAsyncCheck(checkHandle);
<input {...handle.input} {...taken.props} />
{handle.error !== undefined && <p>{handle.error}</p>}
<button disabled={taken.isChecking} type="submit">
Sign up
</button>A Server Action works as the function as it is.
The answer arrives like any other error
The answer is applied to the field with setCustomValidity, so it is treated like a built-in check and its message arrives in field()’s error. Nothing separate is needed to show it.
isChecking is true while an answer is outstanding. Disable the submit button with it, and nothing is sent before the answer is in.
When it asks
It asks only when the person leaves the field, never on every keystroke.
A few more rules keep it from asking needlessly or showing a stale answer.
- Leaving the field with the same value the last answer was about does not ask again.
- When answers arrive out of order, only the one for the newest value is used.
- Emptying the field and leaving it clears the last answer.
- When the request itself fails, nothing is shown; the server still checks the submission.
Note
The answer is only guidance while typing: the name may be taken by someone else before the form is sent, so check again in the Server Action.
Try a taken name
This demo stands in for the server with a function in the browser. admin, k8o and ordo are taken.
Try it
- Type
adminand leave the field. After a moment, the error says it is taken. - While it waits, “Checking” shows and the “Sign up” button cannot be pressed.
- Change it to another name and leave the field. The error goes away.