@k8ordo/form

うまく動かないとき

よくつまずく症状と、その原因、直し方をまとめています。

このページの内容

parseFormが「FormDataに無い」というエラーを投げる

原因

スキーマにある入力欄の名前が、送信されたFormDataにありません。多くの場合、その入力欄にinputを展開し忘れているか、条件によって入力欄を描いていません。

直し方

すべての入力欄にinputを展開し、.optional()の付いたオブジェクトの中の入力欄も必ず描きます。何も選ばなければ値を送らないラジオボタンや<select>、チェックボックスは、このエラーの対象外です。

.optional()を付けたのに、空欄のままだと通らない

原因

空のテキスト欄は、値が無いのではなく""を送ります。.optional()は値が無い場合を許すだけなので、.min(1)のような検証は""に対してそのまま働きます。

直し方

空欄を許したいときは、z.union([z.literal(''), z.string().min(3)])のように""を受け付けるスキーマを書きます。ただしこの場合、.min(3)はどちらの枝を確かめるか決まらないため、ブラウザでは確かめずdroppedに載ります。

zod/miniで書いたら、文言が「Invalid input」になる

原因

zod/miniは、バンドルを小さく保つために、文言の辞書を自動では読み込みません。辞書が無いと、どのエラーもInvalid inputになります。

直し方

サーバーで最初に読み込まれるモジュールでz.config(z.locales.ja())のように辞書を読み込むか、スキーマの検証ごとに文言を書きます。

送信に失敗したあと、ラジオボタンの選択が戻らない

原因

自分で書いたラジオボタンにinputをそのまま展開しています。送信のあとはinputに前回の値がdefaultValueとして入り、各ラジオボタンのvalueとぶつかります。

直し方

inputからはnameとrequiredだけを渡し、state.valuesを見て選択肢ごとにdefaultCheckedを決めます。@k8ordo/uiのRadioとRadioCardなら、そのまま展開できます。

同じ失敗を返すと、2回目はフォーカスが移らない

原因

useFormは、返ってきたstateを中身とtokenで見分けます。自分で組み立てたstateに新しいtokenが無いと、同じ内容の2回目の失敗は前と同じ返事とみなされます。

直し方

parseFormが返したstateを広げて使うか、自分で組み立てるときは毎回新しいtokenを入れます。

隠れたステップのエラーにフォーカスが移らない

原因

hiddenの付いたステップの中の入力欄は、フォーカスを受け取れません。

直し方

新しいstateが届いたら、エラーのあるステップへ描画の中で切り替えます。詳しくは「複数ステップのフォーム」を見てください。

stringboolのチェックボックスが「on」を送る

原因

@k8ordo/uiのCheckboxには、展開したvalueが届きません。そのため、ブラウザの既定のonが送られます。

直し方

z.stringbool()の欄は、素の<input {...field.input} />で描きます。

NumberFieldの範囲のエラーだけ、文言がzodと違う

原因

NumberFieldはtype="text"で描くので、ブラウザはminとmaxを確かめません。範囲の外の値はNumberFieldが自分で知らせ、その文言は@k8ordo/uiの辞書のものです。

直し方

文言をzodにそろえたいときは、TextFieldにtype="number"のまま展開します。ブラウザが範囲を確かめ、useFormがzodの文言を出します。

k8ordo

Baselineに入った機能を、制限なく使うReactのライブラリ群。

© 2026 k8o — MIT License

組版:Noto Sans JP / M PLUS 2