入力中にサーバーへ問い合わせる
ユーザー名がすでに使われているかどうかは、サーバーに問い合わせないと分かりません。送信してから知らせるより、入力欄を離れた時点で知らせたほうが、直す手間が少なく済みます。useAsyncCheckは、この問い合わせを1つの入力欄に付けます。
このページの内容
入力欄に問い合わせを付ける
useAsyncCheckに、値を受け取って文言を返す関数を渡します。問題が無ければundefinedを返します。返ってきたpropsは、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>問い合わせる関数には、Server Actionをそのまま使えます。
ほかのエラーと同じ場所に出る
サーバーの返事は、setCustomValidityで入力欄に付けます。そのため組み込みの検証と同じように扱われ、文言はfield()のerrorに届きます。表示のために別の仕組みを用意する必要はありません。
返事を待っている間はisCheckingがtrueになります。送信ボタンを押せないようにしておけば、答えが出る前に送られることはありません。
問い合わせるタイミング
問い合わせるのは、入力欄から離れたときだけです。キーを押すたびにサーバーへ問い合わせることはありません。
ほかにも、無駄な問い合わせや古い返事を避けるための決まりがあります。
- 前回の返事と同じ値のまま入力欄を離れても、問い合わせ直しません。
- 返事が前後して届いても、最後に問い合わせた値の返事だけを使います。
- 入力欄を空にして離れると、前の返事は消えます。
- 問い合わせ自体が失敗したときは、何も表示しません。送信されたあとに、サーバーが改めて検証します。
情報
メモ
問い合わせの結果は、あくまで入力中の案内です。名前は送信までの間にほかの人に取られることもあるので、Server Actionの中でも必ず確かめてください。
Playground
使われている名前を試す
このデモでは、サーバーへの問い合わせをブラウザの中の関数で置き換えています。admin、k8o、ordoが使用済みです。
試してみる
adminと入力して入力欄から離れると、少し待ったあとに使われているというエラーが出ます。- 返事を待っている間は、「確認しています」と表示され、「登録」ボタンは押せません。
- 別の名前に変えて入力欄から離れると、エラーが消えます。