React Hook Form は Reack のバリデーションライブラリの一つです。 Hook の名が示す通り関数コンポーネントの Hook 機能を使ってバリデーション用のモジュールを提供してくれます。
ホーム | React Hook Form – Simple React forms validation
yup はバリデーションルールを定義するためのライブラリです。メソッドチェーン的にルールを決定できます。
React Hook Form と yup を組み合わせることでフォームのバリデーション定義を分かりやすく作れます。デモは次です。
はじめる | React Hook Form – Simple React forms validation#スキーマバリデーション
これは次の記述で実現されています。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | import React from "react" ; import { useForm } from "react-hook-form" ; import { yupResolver } from '@hookform/resolvers' ; import * as yup from "yup" ; // yup によるバリデーションルール定義 // schema の名らしく一構造体にまとめて記述できる const schema = yup.object().shape({ firstName: yup.string().required(), age: yup.number().positive().integer().required(), }); export default function App() { // バリデーション機能を呼び出し // yupResolver(schema) で上述の yup ルールを採用 const { register, handleSubmit, errors } = useForm({ resolver: yupResolver(schema) }); const onSubmit = data => console.log(data); return ( <form onSubmit={handleSubmit(onSubmit)}> { /* ref={register} でバリデーション機能に登録されます */ } <input type= "text" name= "firstName" ref={register} /> { /* errors はバリデーションエラー内容を持つ構造体で自動で更新されます */ } <p>{errors.firstName?.message}</p> <input type= "text" name= "age" ref={register} /> <p>{errors.age?.message}</p> <input type= "submit" /> </form> ); } |
シンプルで読みやすく書きやすいです。例だけでもバリデーションとしては十分ですが日本語に対応できていません。日本語に対応したデモが次です。
これは次の様なコードで実現しています。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 | /*** LocaleJP.js ***/ // 日本語のルールと文言の対応を定義 export const LocaleJP = { mixed: { default : '${path}は無効です' , required: '${path}は必須フィールドです' , oneOf: '${path}は次の値のいずれかでなければなりません:${values}' , notOneOf: '${path}は次の値のいずれかであってはなりません:${values}' , }, string: { length: '${path}は正確に${length}文字でなければなりません' , min: '${path}は少なくとも${min}文字でなければなりません' , max: '${path}は最大${max}文字でなければなりません' , matches: '${path}は次と一致する必要があります: "${regex}"' , email: '${path}はメールアドレス形式である必要があります' , url: '${path}は有効なURLでなければなりません' , trim: '${path}はトリミングされた文字列でなければなりません' , lowercase: '${path}は小文字の文字列でなければなりません' , uppercase: '${path}は大文字の文字列でなければなりません' , }, number: { min: '${path}は${min}以上である必要があります' , max: '${path}は${max}以下でなければなりません' , lessThan: '${path}は${less}より小さくなければなりません' , moreThan: '${path}は${more}より大きくなければなりません' , notEqual: '${path}は${notEqual}と等しくない必要があります' , positive: '${path}は正の数でなければなりません' , negative: '${path}は負の数でなければなりません' , integer: '${path}は整数でなければなりません' , }, date: { min: '${path}フィールドは${min}より後でなければなりません' , max: '${path}フィールドは${max}より前でなければなりません' , }, object: { noUnknown: '${path}フィールドには,オブジェクトシェイプで指定されていないキーを含めることはできません' , }, array: { min: '${path}フィールドには少なくとも${min}の項目が必要です' , max: '${path}フィールドには${max}以下の項目が必要です' , }, }; /*** BaseYup.js ***/ import { LocaleJP } from '@/validation/LocaleJP' ; import * as yup from 'yup' ; // yup に作った日本語メッセージを定義 yup.setLocale(LocaleJP); // yup は import する度に setLocale する必要があるので setLocale 済みの yup を呼び出せるように export export const BaseYup = yup; /*** form.jsx ***/ // 上述の BaseYup を仕様 import { BaseYup } from "./BaseYup" ; // スキーマの末尾に label と付けてフィールドごとの自然言語名を定義 const SignupSchema = BaseYup.object().shape({ firstName: BaseYup.string().required().label( "名" ), lastName: BaseYup.string().label( "姓" ), age: BaseYup.number().required().positive().integer().label( "年齢" ), website: BaseYup.string().url().label( "WebサイトURL" ) }); |
例では基本ルールのみでしたが yup は任意の関数とメッセージによるカスタムルールにも対応しています。こんな感じで React Hook Form と yup によってあっという間にバリデーション用のロジックを作れます。ロジックを作ったならばあとはデザインフレームワークなり手製のCSSなりのエラー表記と繋げるだけでバリデーション機能完成です。