【React】React Hook Form と yup でフォームのバリデーションを作る

 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なりのエラー表記と繋げるだけでバリデーション機能完成です。

>株式会社シーポイントラボ

株式会社シーポイントラボ

TEL:053-543-9889
営業時間:9:00~18:00(月〜金)
住所:〒432-8003
   静岡県浜松市中央区和地山3-1-7
   浜松イノベーションキューブ 315
※ご来社の際はインターホンで「316」をお呼びください

CTR IMG