React Hook FormのdirtyFieldsを使った。
今回はreact hook formのdirtyFieldsを紹介
変更されたフォームを監視して、どのフォームが変更されたかを瞬時に教えてくれます。
↓react-hook-form公式の説明文を記載
日本語訳すると、
以下のようになります。
ユーザーが変更したフィールドを持つオブジェクト。ライブラリが比較できるように、すべての入力をdefaultValues経由で提供してください。useFormdefaultValues.
重要:defaultValues必ず をで提供してくださいuseForm。そうすることで、フック フォームは各フィールドのダーティさを比較するための唯一の真実のソースを持つことができます。
ダーティフィールドはとして表示されませんisDirty formState。これは、ダーティフィールドがフォーム全体ではなくフィールドレベルで「フィールドダーティ」とマークされるためです。フォーム全体の状態を確認したい場合は、isDirty代わりに を使用してください。
少しわかりづらいですが、要点をまとめると、
・useFormで全ての入力フィールドのdefaultValuesを指定すること。
・dirtyFieldsはフィールド単位で変更された状態を示し、isDirtyは、フォーム全体の状態を判断する。
実際に試してみる。
"use client";
import { useEffect } from "react";
import { useFormContext } from "react-hook-form";
export default function Home() {
const {
register,
formState: { dirtyFields },
} = useFormContext();
useEffect(() => {
console.log(dirtyFields);
}, [dirtyFields]);
return (
<div className="p-10">
<form className="flex flex-col gap-6">
<div className="flex flex-col">
<label htmlFor="name">ユーザー名</label>
<input
id="name"
{...register("name")}
type="text"
className="border rounded-2xl"
/>
</div>
<div className="flex flex-col">
<label htmlFor="email">メールアドレス</label>
<input
id="email"
{...register("email")}
type="email"
className="border rounded-2xl"
/>
</div>
</form>
</div>
);
}
↓最初は空のオブジェクトが返ってくる。
↓ユーザー名の項目に一文字入力した瞬間にtrueのオブジェクトが返ってくる。
↓メールアドレスも、一文字入力した瞬間にtrueが返ってくる。
少し応用
"use client";
import { useEffect } from "react";
import { useFormContext } from "react-hook-form";
export default function Home() {
const {
register,
setValue, // ←追加
formState: { dirtyFields },
} = useFormContext();
useEffect(() => {
console.log(dirtyFields);
}, [dirtyFields]);
// ↓追加
useEffect(() => {
setValue("name", "初心者エンジニア");
}, []);
// ↑追加
return (
<div className="p-10">
<form className="flex flex-col gap-6">
<div className="flex flex-col">
<label htmlFor="name">ユーザー名</label>
<input
id="name"
{...register("name")}
type="text"
className="border rounded-2xl"
/>
</div>
<div className="flex flex-col">
<label htmlFor="email">メールアドレス</label>
<input
id="email"
{...register("email")}
type="email"
className="border rounded-2xl"
/>
</div>
</form>
</div>
);
}
↓初期状態をセットしたときでも、最初は空のオブジェクトが返ってくるようです。
↓一文字変えた瞬間にtrueが返ってくる。
上記のように個別のフォームごとに状態を監視して処理を行いたい場合は、dirtyFieldsが非常に便利だと思います。
今回defaultValuesを一切指定していなかったのですが、うまく使うことができたようです。
しかし、公式ではdefaultValuesの指定を推奨しているので、指定したほうがいいでしょう。
Discussion