📑
React Hook Formを使ってユーザーの操作によってバリデーションを動的に変更する
やりたいこと
- 入力の不要/必須の切り替えができるテキストエリアを作りたい
- チェックボックスがtrueの場合はテキストエリアが入力でき、必須項目になる
- チェックボックスがflseの場合はテキストエリアが入力できない
コンポーネントのイメージ
チェックボックスが押されていない場合
- このときにはテキストエリアに入力できない
- 送信ボタンを押した場合は、フォームが送信される
チェックボックスを押した場合
- テキストエリアが空の場合は、送信ボタンを押してもフォームが送信されない
- テキストエリアに何か入力した場合は、送信ボタンを押してフォームを送信できる
実装
import { FC } from "react";
import { useForm, useWatch } from "react-hook-form";
type FormFields = {
isTextEnabled: boolean;
text?: string;
};
export const SampleForm: FC = () => {
const {
register,
handleSubmit,
control,
formState: { errors },
} = useForm<FormFields>({
defaultValues: {
isTextEnabled: false,
text: undefined,
},
});
const isTextEnabled = useWatch({
control,
name: "isTextEnabled",
});
const onSubmit = () => {
window.alert("送信完了");
};
return (
<form onSubmit={handleSubmit(onSubmit)}>
<div>
<input type="checkbox" {...register("isTextEnabled")} />
<label>備考を入力する</label>
</div>
<div>
<textarea
disabled={!isTextEnabled}
{...register("text", {
required: isTextEnabled ? "備考は必須項目です" : false,
})}
/>
{errors.text && <p>{errors.text.message}</p>}
</div>
<button type="submit">送信</button>
</form>
);
};
ポイント
useWatch()
を使い、チェックボックスであるisTextEnabled
の値を監視する。
const isTextEnabled = useWatch({
control,
name: "isTextEnabled",
});
isTextEnabled
の値によって、備考の入力欄であるtext
のrequired
を変化させる。
<textarea
disabled={!isTextEnabled}
{...register("text", {
required: isTextEnabled ? "備考は必須項目です" : false,
})}
/>
Discussion