@k8ordo/form

既存のデータを編集する

登録済みのデータを編集するフォームでは、入力欄に今の値を入れた状態で描きます。このページでは、今の値の渡し方と、変更があるかどうかをisDirtyで知る方法、元に戻す操作を紹介します。

このページの内容

今の値を入力欄に入れる

今の値はdefaultValueで渡します。チェックボックスならdefaultCheckedです。値はDOMが持つので、valueで制御する必要はありません。

edit-talk-form.tsx
const title = form.field('title');
const isPublic = form.field('public');

<input defaultValue={talk.title} {...title.input} />
<input defaultChecked={talk.public} {...isPublic.input} />

defaultValueは、inputを展開する前に書いてください。送信に失敗したあとは、inputに送信した値がdefaultValueとして入ります。後ろに展開したinputが前の値を上書きするので、失敗のあとは送信した値が、それ以外のときは今の値が入力欄に入ります。

警告

落とし穴

inputのあとにdefaultValueを書くと、送信に失敗したときも今の値で上書きしてしまい、入力した内容が消えます。

変更があるかどうかを知る

form.isDirtyは、どれかの入力欄の値が描画したときから変わっていればtrueになります。行の追加や削除も変更として数えます。

値を比べる相手は、入力欄のdefaultValueです。DOMから直接読むので、キーを押すたびに再描画されることはなく、isDirtyが切り替わるときだけ描き直されます。

たとえば、変更を保存せずにページを離れようとしたときに確認を出せます。

edit-talk-form.tsx
useEffect(() => {
  if (!form.isDirty) return;
  const confirm = (event: BeforeUnloadEvent) => {
    event.preventDefault();
  };
  addEventListener('beforeunload', confirm);
  return () => {
    removeEventListener('beforeunload', confirm);
  };
}, [form.isDirty]);
警告

落とし穴

送信ボタンをdisabled={!form.isDirty}で止めるのはおすすめしません。サーバーが描いたHTMLではisDirtyがまだfalseなので、JavaScriptが届くまでボタンを押せません。また、送信に失敗したあとは送信した値が新しい初期値になるため、何も直さずに送り直すこともできなくなります。

元に戻す

type="reset"のボタンを押すと、ブラウザがすべての入力欄をdefaultValueに戻します。useFormはこのリセットに気づき、表示していたエラーを消してisDirtyをfalseに戻します。

tsx
<button type="reset">Revert</button>

Server Actionが終わったあと、Reactもフォームを同じようにリセットします。送信に失敗しても入力が消えないのは、送信した値がdefaultValueとして描かれ、リセットがその値に戻すからです。

Playground

変更のある状態を試す

登録済みの登壇情報を編集するフォームです。今の値をdefaultValueで渡しています。

状態変更なし

試してみる

  1. タイトルを書き換えると、「変更あり」の表示に変わります。
  2. 書き換えた文字を消して元のタイトルに戻すと、「変更なし」に戻ります。
  3. 公開のチェックを外してから「元に戻す」を押すと、値も表示も元に戻ります。
k8ordo

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

© 2026 k8o — MIT License

組版:Noto Sans JP / M PLUS 2