はじめに
この記事はReact Hook Form と zod を使ったフォームの作り方の備忘録です。
間違っている部分がありましたらコメントで教えてもらえると嬉しいです。
使うライブラリについて
React Hook Form は 入力された値を取得するために使います。
zod は 入力された値のバリデーションのために使います。
本来 React Hook Form のみでバリデーション実装も可能なのですが
zod をバリデーションとして使うことで
バリデーション条件を JSX から分離して分かりやすくします。
インストール
npm install react-hook-form
npm install @hookform/resolvers zod
React Hook Form を使ったフォームの作り方
まず React Hook Form だけを使ってフォームの挙動を確認します。
import { useForm } from 'react-hook-form';
function App() {
const { register, handleSubmit } = useForm();
const onSubmit = (data) => console.log(data);
return (
<div className="App">
<form onSubmit={handleSubmit(onSubmit)}>
<div>
<label htmlFor="email">Email</label>
<input id="email" {...register('email')} />
</div>
<div>
<label htmlFor="password">Password</label>
<input id="password" {...register('password')} type="password" />
</div>
<button type="submit">ログイン</button>
</form>
</div>
);
}
input要素 に渡した register関数の引数 が キーになるオブジェクト が
handleSubmit関数 の第1引数に渡した callback関数 の引数に渡ります。
この例の場合、 onSubmit関数 の引数 data に渡ります。
例えば
email.input の入力内容は data.email に
password.input の入力内容は data.password に 代入されます。
zod でバリデーションを実装する
次に zod を React Hook Form に適用してバリデーションを実装します。
import { useForm } from 'react-hook-form';
import { zodResolver } from "@hookform/resolvers/zod"
import * as z from "zod"
const schema = z.object({
email: z.string().email().min(1),
password: z.string().min(1)
});
function App() {
const { register, handleSubmit, formState: { errors } } = useForm({
resolver: zodResolver(schema)
});
const onSubmit = (data) => console.log(data);
console.log(errors);
return (
<div className="App">
<form onSubmit={handleSubmit(onSubmit)}>
<div>
<label htmlFor="email">Email</label>
<input id="email" {...register('email')} />
</div>
<div>
<label htmlFor="password">Password</label>
<input id="password" {...register('password')} type="password" />
</div>
<button type="submit">ログイン</button>
</form>
</div>
);
}
React Hook Form でフォームの挙動を確認した時との違いは
1.変数schema にバリデーションするルールを記述している
2.useFormの引数 にzodのバリデーションを追加している
3.useFormの戻り値 から formState.errors を分割代入で取得している
これら3つのうち 1と2 でバリデーションを追加しています。
バリデーションのエラーは分割代入で取得した formState.errors に代入されます。
formState.erros に代入されるオブジェクトはこのような形になっています。
なので formState.erros を JSX 内で使うことでバリデーションエラーを描画出来ます。
import { useForm } from 'react-hook-form';
import { zodResolver } from "@hookform/resolvers/zod"
import * as z from "zod"
const schema = z.object({
email: z.string().email().min(1),
password: z.string().min(1)
});
function App() {
const { register, handleSubmit, formState: { errors } } = useForm({
resolver: zodResolver(schema)
});
const onSubmit = (data) => console.log(data);
console.log(errors);
return (
<div className="App">
<form onSubmit={handleSubmit(onSubmit)}>
<div>
<label htmlFor="email">Email</label>
<input id="email" {...register('email')} />
<p>{errors.email?.message}</p>
</div>
<div>
<label htmlFor="password">Password</label>
<input id="password" {...register('password')} type="password" />
<p>{errors.password?.message}</p>
</div>
<button type="submit">ログイン</button>
</form>
</div>
);
}
バリデーションエラーの文言を変更する
import { useForm } from 'react-hook-form';
import { zodResolver } from "@hookform/resolvers/zod"
import * as z from "zod"
const schema = z.object({
email: z.string().email({ message: "メールアドレスの形式で入力してください。"}).min(1, { message: "1文字以上で入力する必要があります。"}),
password: z.string().min(1, { message: "1文字以上で入力する必要があります。"})
});
function App() {
const { register, handleSubmit, formState: { errors } } = useForm({
resolver: zodResolver(schema)
});
const onSubmit = (data) => console.log(data);
console.log(errors);
return (
<div className="App">
<form onSubmit={handleSubmit(onSubmit)}>
<div>
<label htmlFor="email">Email</label>
<input id="email" {...register('email')} />
<p>{errors.email?.message}</p>
</div>
<div>
<label htmlFor="password">Password</label>
<input id="password" {...register('password')} type="password" />
<p>{errors.password?.message}</p>
</div>
<button type="submit">ログイン</button>
</form>
</div>
);
}
変数schema のバリデーションルールに変更を加えると 任意の文言 に変更出来ます。
詳しくは zod の公式ドキュメントに乗っています。
さいごに
学習させていただいた先・ライブラリの公式ドキュメントです。