React Hook Formは、Reactアプリケーションにおけるフォーム管理を簡素化するための強力なライブラリです。特に、useForm
カスタムフックは、フォームの状態管理やバリデーションルールの設定を容易にする中心的な機能です。
基本的な使用例
以下は、useForm
フックを使用した基本的な例です。
import React from 'react';
import { useForm } from 'react-hook-form';
interface FormValues {
firstName: string;
lastName: string;
email: string;
}
const MyForm: React.FC = () => {
const { register, handleSubmit, errors } = useForm<FormValues>();
const onSubmit = (data: FormValues) => {
console.log(data);
};
return (
<form onSubmit={handleSubmit(onSubmit)}>
<input name="firstName" ref={register({ required: true })} />
{errors.firstName && <span>This field is required</span>}
<input name="lastName" ref={register({ required: true })} />
{errors.lastName && <span>This field is required</span>}
<input name="email" ref={register({ required: true, pattern: /^\S+@\S+$/i })} />
{errors.email && <span>This field is required and must be a valid email</span>}
<button type="submit">Submit</button>
</form>
);
};
export default MyForm;
上記の例では、useFormフックを使用してフォームの状態を管理し、registerメソッドを使用して各入力要素をフォームに登録しています。handleSubmitメソッドは、フォームの送信時に呼び出され、フォームデータを引数として受け取ります。errorsオブジェクトを使用して、バリデーションエラーを表示しています。
フォームの設定とカスタマイズ
useFormフックには、いろいろな設定ができるプロパティがあります。これらのプロパティを使うと、フォームの動きをカスタマイズできます。
例えば、modeっていうオプションがあるんですが、これを使うと、ユーザーがフォームを送信する前にいつバリデーション(入力チェック)をするかを選べます。
- onSubmit: フォームを送信したときにバリデーションをする
- onBlur: 入力欄からフォーカスが外れたときにバリデーションをする
- onChange: 入力欄の内容が変更されるたびにバリデーションをする
- onTouched: 入力欄に一度でもフォーカスがあたったあと、フォーカスが外れたときにバリデーションをする
こんな感じで、バリデーションのタイミングを自分で決められるんですよ。他にも、フォームの初期値を設定したり、エラーメッセージの表示方法を変えたりできるプロパティがあります。
const { register, handleSubmit, errors } = useForm<FormValues>({
mode: 'onBlur',
defaultValues: {
firstName: 'John',
lastName: 'Doe',
email: 'johndoe@example.com',
},
});
スキーマバリデーションのプロパティには、resolverとcontextがあります。resolverを使用すると、好みのスキーマバリデーションライブラリ(例えば、Yup、Joi、Superstruct)と統合できます。これにより、複雑なバリデーションルールを定義し、フォームの入力値を効果的に検証できます。contextプロパティは、スキーマバリデーションに追加のコンテキストを提供するために使用されます。
import * as yup from 'yup';
import { yupResolver } from '@hookform/resolvers/yup';
const schema = yup.object().shape({
firstName: yup.string().required(),
lastName: yup.string().required(),
email: yup.string().email().required(),
});
const { register, handleSubmit, errors } = useForm<FormValues>({
resolver: yupResolver(schema),
});
バリデーションルールの適用
registerメソッドは、入力要素やselect要素をReact Hook Formに登録し、バリデーションルールを適用するために使用されます。HTML標準に基づくバリデーションルール(required、min、max、minLength、maxLength、patternなど)に加えて、カスタムバリデーションメソッドを定義することもできます。これにより、アプリケーションの要件に合わせた柔軟なバリデーションが可能になります。
const { register, handleSubmit, errors } = useForm<FormValues>();
<input
name="age"
ref={register({
required: true,
min: 18,
max: 99,
validate: (value) => value % 2 === 0,
})}
/>;
初期値の設定
defaultValueは、フォームの初期値を設定するために使用されます。defaultValuesに、初期値を持ったオブジェクトを渡すだけで、フォームの各入力欄に初期値が表示されるようになります。
初期値を設定しておくと、ユーザーが情報を編集するときに、現在の値を参考にしながら編集できるので、とても便利ですよね。
また、フォームをリセットするときにも、defaultValuesで設定した初期値に戻すことができます。
フォームの状態管理
useFormフックから返されるオブジェクトには、フォーム全体の状態に関する情報が含まれています。例えば、isDirtyプロパティは、ユーザーが入力要素を変更するとtrueに設定されます。isValidプロパティは、フォームが有効な状態であるかどうかを示します。isSubmittingプロパティは、フォームが送信中であるかどうかを示します。これらのプロパティを使用して、フォームの状態に基づいて条件付きのUI表示やアクションを実行できます。
const { formState: { isDirty, isValid, isSubmitting } } = useForm<FormValues>();
return (
<form onSubmit={handleSubmit(onSubmit)}>
{/* ... */}
<button type="submit" disabled={!isValid || isSubmitting}>
{isSubmitting ? 'Submitting...' : 'Submit'}
</button>
{isDirty && <p>Form has unsaved changes.</p>}
</form>
);
値の監視
watchメソッドは、指定した入力要素の値の変更を監視し、その値を返します。これは、他の入力要素の値に基づいて動的に値を更新する場合に便利です。例えば、パスワードの確認フィールドを実装する際に、watchメソッドを使用してパスワードの入力値を監視し、確認フィールドの値と比較することができます。
const password = watch('password');
return (
<form onSubmit={handleSubmit(onSubmit)}>
<input name="password" ref={register({ required: true })} />
<input
name="confirmPassword"
ref={register({
required: true,
validate: (value) => value === password,
})}
/>
{errors.confirmPassword && <span>Passwords do not match</span>}
{/* ... */}
</form>
);
エラーハンドリングとリセット
React Hook Formは、エラーハンドリングやフォームのリセットなどの一般的なフォーム機能も提供しています。errorsオブジェクトを使用して、バリデーションエラーを簡単に表示できます。resetメソッドを使用して、フォームの状態をリセットできます。
const { register, handleSubmit, errors, reset } = useForm<FormValues>();
const onSubmit = (data: FormValues) => {
console.log(data);
reset();
};
return (
<form onSubmit={handleSubmit(onSubmit)}>
{/* ... */}
<button type="button" onClick={() => reset()}>
Reset
</button>
</form>
);
他のライブラリやツールとの連携
また、React Hook Formは、他のライブラリやツールと連携することができます。例えば、Material-UIやBootstrapなどのUIライブラリと組み合わせて、美しくて使いやすいフォームを作成できます。また、Redux、MobX、Recoilなどの状態管理ライブラリと組み合わせて、アプリケーション全体の状態を管理することもできます。
まとめ
React Hook Formは、開発者にとって効率的でユーザーフレンドリーなフォームを作成するための強力なツールです。シンプルなAPIと柔軟なカスタマイズ機能により、さまざまなアプリケーションの要件に対応できます。フォームの状態管理やバリデーションを手動で実装する必要がなくなるため、開発者はビジネスロジックに集中することができます。