Open4
React Hook Form の導入
概要
- 公式:https://react-hook-form.com/
- Reactアプリケーションでフォーム処理を簡単かつ効率的に行うためのライブラリ
インストール
npm install react-hook-form
基本的な使い方(JS)
- まずは先にJSでの基本を抑えておく
useForm
register
handleSubmit
例
example.js
import { useForm } from "react-hook-form"
export default function App() {
const {
register,
handleSubmit,
watch,
formState: { errors },
} = useForm()
const onSubmit = (data) => console.log(data)
console.log(watch("example")) // watch input value by passing the name of it
return (
/* "handleSubmit" will validate your inputs before invoking "onSubmit" */
<form onSubmit={handleSubmit(onSubmit)}>
{/* register your input into the hook by invoking the "register" function */}
<input defaultValue="test" {...register("example")} />
{/* include validation with required or other standard HTML validation rules */}
<input {...register("exampleRequired", { required: true })} />
{/* errors will return when field validation fails */}
{errors.exampleRequired && <span>This field is required</span>}
<input type="submit" />
</form>
)
}
"react-hook-form"のimport
- まずはimportを行う
import { useForm } from "react-hook-form"
useForm()
から個々の関数を読み込む
カスタムフック const { register, handleSubmit, watch, formState: { errors }, } = useForm();
submit時の関数を用意
-
handleSubmit()
:フォーム送信時にバリデーションを実行し、成功時にデータを処理。 - submit時に実行される関数に
handleSubmit()
指定し、その関数の引数にユーザーが定義した関数(onSubmit()
)を指定してやる
const onSubmit = (data) => console.log(data)
...
return (
/* "handleSubmit" will validate your inputs before invoking "onSubmit" */
<form onSubmit={handleSubmit(onSubmit)}>
...
register関数
import { useForm } from "react-hook-form"
export default function App() {
const { register, handleSubmit } = useForm()
const onSubmit = (data) => console.log(data)
return (
<form onSubmit={handleSubmit(onSubmit)}>
<input {...register("firstName", { required: true, maxLength: 20 })} />
<input {...register("lastName", { pattern: /^[A-Za-z]+$/i })} />
<input type="number" {...register("age", { min: 18, max: 99 })} />
<input type="submit" />
</form>
)
}
-
register
: 各入力フィールドをフォームに登録し、バリデーションルールを設定する。 - バリデーションの設定方法:
-
register
の第2引数に指定する <input {...register("exampleRequired", { required: true })} />
-
- バリデーションの種類:
- 公式:https://react-hook-form.com/docs/useform/register
- required
- min
- max
- minLength
- maxLength
- pattern
- validate
エラー処理
import React from "react";
import { useForm } from "react-hook-form";
const BasicForm = () => {
const { register, handleSubmit, formState: { errors } } = useForm();
const onSubmit = (data) => {
console.log("フォームデータ:", data);
};
return (
<form onSubmit={handleSubmit(onSubmit)}>
{/* 名の入力フィールド */}
<div>
<label htmlFor="firstName">名</label>
<input
id="firstName"
{...register("firstName", { required: "名は必須です。" })}
aria-invalid={errors.firstName ? "true" : "false"}
/>
{errors.firstName && (
<span role="alert" style={{ color: "red" }}>
{errors.firstName.message}
</span>
)}
</div>
{/* メールアドレスの入力フィールド */}
<div>
<label htmlFor="email">メールアドレス</label>
<input
id="email"
type="email"
{...register("email", {
required: "メールアドレスは必須です。",
pattern: {
value: /^\S+@\S+$/i,
message: "有効なメールアドレスを入力してください。",
},
})}
aria-invalid={errors.email ? "true" : "false"}
/>
{errors.email && (
<span role="alert" style={{ color: "red" }}>
{errors.email.message}
</span>
)}
</div>
{/* 送信ボタン */}
<button type="submit">送信</button>
</form>
);
};
export default BasicForm;
-
const { register, handleSubmit, formState: { errors } } = useForm();
- フォームのバリデーションエラーを含むオブジェクト(
errors
)を読み込む
- フォームのバリデーションエラーを含むオブジェクト(
-
formState
とは-
formState
は、フォームの状態に関する情報を保持するオブジェクト - 主なプロパティには以下
-
isDirty
: フォームが変更されたかどうかを示します。 -
isValid
: フォームのバリデーションが成功しているかどうかを示します。 -
errors
: フォームフィールドに関連するバリデーションエラーを保持します。- 各フィールド名をキーとして、そのフィールドに対応するエラー情報(メッセージやエラーレベルなど)が値として格納されます。
-
{ "fieldName": { "type": "validationType", "message": "エラーメッセージ" }, // 他のフィールド... }
-
fieldName
: エラーが発生したフィールドの名前。 -
type
: バリデーションの種類(例: required, minLength)。 -
message
: エラーメッセージ。
-
-
- オブジェクトの分割代入 (destructuring assignment)については以下を参照
- https://typescriptbook.jp/reference/values-types-variables/object/destructuring-assignment-from-objects
-
入れ子構造の分割代入
const continent = { name: "北アメリカ", us: { name: "アメリカ合衆国", capitalCity: "ワシントンD.C.", }, }; const { us: { name, capitalCity }, } = continent; console.log(name); console.log(capitalCity);
基本的な使い方(TS)
- JSとの差分だけを以下に記載する
- 公式:https://react-hook-form.com/ts#SubmitHandler
useForm
にジェネリック型パラメータを指定する
-
useForm<T>()
のように、ジェネリック型パラメータを指定することで、フォームの型構造を定義できる
SubmitHandler
-
SubmitHandler
は、React Hook FormをTypeScriptと共に使用する際に非常に役立つ型定義 - 具体的には、フォームの送信時に呼び出される関数の型を定義するために使用される
- これにより、フォームデータの型安全性を確保し、開発中のエラーを減らすことができる
- 具体的な型定義は
type SubmitHandler<TFieldValues extends FieldValues> = (
data: TFieldValues,
event?: React.BaseSyntheticEvent
) => unknown | Promise<unknown>;
- TFieldValuesは、フォームのフィールド値の型を表すジェネリック型パラメータです。
- dataパラメータは、送信されたフォームデータを含むオブジェクトです。
- eventパラメータは、フォーム送信イベントを表すオプションのパラメータです。
- 戻り値の型はunknownまたはPromise<unknown>で、非同期処理も可能であることを示しています。
- GitHub:https://github.com/react-hook-form/react-hook-form/blob/master/src/types/form.ts
サンプル
enum GenderEnum {
female = "female",
male = "male",
other = "other",
}
interface IFormInput {
firstName: string
gender: GenderEnum
}
import ReactDOM from "react-dom"
import { useForm, SubmitHandler } from "react-hook-form"
enum GenderEnum {
female = "female",
male = "male",
other = "other",
}
interface IFormInput {
firstName: string
gender: GenderEnum
}
export default function App() {
const { register, handleSubmit } = useForm<IFormInput>()
const onSubmit: SubmitHandler<IFormInput> = (data) => console.log(data)
return (
<form onSubmit={handleSubmit(onSubmit)}>
<label>First Name</label>
<input {...register("firstName")} />
<label>Gender Selection</label>
<select {...register("gender")}>
<option value="female">female</option>
<option value="male">male</option>
<option value="other">other</option>
</select>
<input type="submit" />
</form>
)
}