⚠️ 問題の概要
API から取得したデータをフォームの初期値に設定したいのに、defaultValues
が期待通りに動作しないケースがあります。
// ❌ これだと初期値が設定されない
const { data: customerRes } = useGetCustomer({ request: { customerId } });
const methods = useForm<CustomerFormValues>({
defaultValues: {
firstName: customerRes?.customer?.firstName, // undefined のままキャッシュされる
lastName: customerRes?.customer?.lastName,
},
});
原因: defaultValues
は初回レンダリング時の値がキャッシュされるため、後から API レスポンスが取得されても反映されません。
defaultValues are cached on the first render within the custom hook. If you want to reset the defaultValues, you should use the reset api.
✨️ 解決方法 1: values を使用(推奨)
React Hook Form v7.40.0 以降では、values
プロパティを使用することで動的にフォームの値を更新できます。
const { data: customerRes } = useGetCustomer({ request: { customerId } });
const methods = useForm<CustomerFormValues>({
defaultValues: {
firstName: "",
lastName: "",
email: "",
},
values: customerRes?.customer, // API レスポンスが取得されたら自動で更新される
});
return (
<form>
<input {...register("firstName")} />
<input {...register("lastName")} />
<input {...register("email")} />
</form>
);
values の利点
- API データが取得されると自動的にフォームが更新される
-
useEffect
やreset
/setValue
が不要でコードがシンプル - React Hook Form が推奨する公式の解決方法
✨️ 解決方法 2: useEffect + reset/setValue
values
が使用できない場合の代替案です。
const { data: customerRes } = useGetCustomer({ request: { customerId } });
const methods = useForm<CustomerFormValues>({
defaultValues: { firstName: "", lastName: "", email: "" },
});
const { register, setValue } = methods;
useEffect(() => {
if (customerRes?.customer) {
const { customer } = customerRes;
setValue("firstName", customer.firstName || "");
setValue("lastName", customer.lastName || "");
setValue("email", customer.email || "");
}
}, [customerRes?.customer, setValue]);
💡 他にもこんなやり方も
- オブジェクトをハッシュ化したものをkeyとして渡す
- → オブジェクトに変更があるとkeyに渡される文字列が変わる
(ハッシュ関数を使っているので、「深い比較」になる)
- → オブジェクトに変更があるとkeyに渡される文字列が変わる
- → keyが変わるため
HogeForm
がアンマウント→再マウントされる
import hash from 'stable-hash'
const { data } = useHogeQuery();
return <HogeForm key={hash(data)} defaultValues={data} />
🗒️ まとめ
-
推奨:
values
プロパティを使用(v7.40.0 以降) -
代替:
useEffect
+setValue
の組み合わせ - どちらの方法でも API データを動的にフォームに反映可能
values
を使うことで、より簡潔で保守性の高いコードが書けるようになります。