CodeZine(コードジン)

特集ページ一覧

フォームのバリデーションに役立つYupとは? React向けライブラリを解説

現場で役立つ! React向けライブラリ詳説 第2回

  • LINEで送る
  • このエントリーをはてなブックマークに追加
2021/02/12 11:00

 前回に続いて、ブラウザアプリケーションの基本にして王道であるフォームを題材にします。今回は入力値のバリデーションを担当するライブラリとして、Yupについて解説します。入力欄1つひとつにバリデーションルールを定義する作業は、通常であれば面倒なものですが、Yupを使うとスッキリと定義できます。

目次

対象読者

  • JavaScriptとWeb開発の基礎に理解がある方
  • Reactを用いたJavaScriptアプリケーション開発の経験者

前提環境

 筆者の検証環境は以下の通りです。

  • macOS Big Sur 11.1
  • Node.js 15.5.0/npm 7.3.0
  • React 17.0.1
  • react-scripts 4.0.1
  • Formik 2.2.6
  • Yup 0.32.8

バリデーションを宣言的に記述する

 今回はフォームのバリデーションに役立つライブラリ、Yupについて解説します。前回解説した、フォーム作成補助ライブラリのFormikでは、入力内容のバリデーションをリスト1のように記述していました。

[リスト1]Formikの素直なバリデーション
<Formik
  validate={values => {
    const errors = {};
    if (!values.email) {
      errors.email = 'Eメールを入力してください'
    }
    return errors;
  }}
>

 validate属性の関数に、すべての入力欄の値が入ったオブジェクトであるvaluesが渡されるので、それの正否を判定し、もし誤りがあればvaluesオブジェクト内の項目名と同名のキーでerrorsオブジェクトにエラーメッセージを登録することになっていました。データに対してif文を駆使しながら1行ずつ処理を書いて判定してするので、いわゆる手続き的プログラミングの手法でバリデーションルールを実装することになります。

 UIの操作はReactのおかげで宣言的に記述できるようになっています。可能であれば、バリデーションルールの定義も宣言的プログラミングで行いたいですよね。そんな夢を叶えてくれるのが、Yupというバリデーション専門のライブラリです。Yupが生成するバリデーションルールはFormikでも公式サポートされているので、前回の内容と組み合わせることで、より快適にフォームを組み上げられることでしょう。

Yup

 YupはJason Quense氏が開発している、バリデーションのためのライブラリです。

図1:YupのGitHubリポジトリ
図1:YupのGitHubリポジトリ

 GitHubのREADME(説明書)には、Yupは"JavaScript schema builder for value parsing and validation"である、と書かれています。フォームの入力値を解析してバリデーションを行うために、JavaScriptでスキーマ(データ構造)を定義するためのライブラリである、ということです。ただ、スキーマと言われてもピンとこないと思うので、実際の例を見てみましょう。スキーマはリスト2のように、関数のチェーン呼び出しを組み合わせながら定義します。

[リスト2]スキーマを定義する
import * as yup from 'yup';

const schema = yup.object().shape({ // (1)
  name: yup.string().required(), // (2)
  age: yup.number().required().positive().integer(), // (3)
  email: yup.string().email(), // (4)
});

 (1)のyup.object()は、判定対象の入力値がオブジェクトで提供されることを期待する定義です。続いて、実際のデータ構造を.shape()で定義します。(2)はnameという項目が文字列型の必須項目であることを示しています。(3)はageという項目が数値型の必須項目であり、正の整数であることを期待する定義です。(4)はemailという項目が文字列型であり、メールアドレスとして正しい形式であることを期待する定義です。emailにはrequired()が付いていないので、任意入力の項目です。

 Yupのスキーマ定義は、このように各項目の特性を並べるだけで作成できます。バリデーションルールを宣言的に記述できる、魅力的なインターフェースですね。

 さて、本来はフォームに組み込んで使うライブラリですが、単独で動作させるためのインターフェースも用意されています。リスト2のスキーマを使って値を検証する場合は、リスト3のような書き方になります。

[リスト3]Yup単独でバリデーションを実行する
schema
  .isValid({ // (1)
    name: 'Taro',
    age: 24,
  })
  .then(function (valid) { // (2)
    // ...
  });

 Yupのスキーマオブジェクト(リスト2で作成したschema)には、データを検証するための関数として(1)のisValidが用意されています。スキーマの最上位のデータ型としてobject()を定義していたので、isValidに渡すデータもオブジェクトです。バリデーションは非同期で行われ、Promiseで返却されます。(2)のように.then()にコールバック関数を登録することで、入力値の正否をboolean型で受け取れるので、これを受けて次の処理を実施することになります。これがYupの最もシンプルな使い方です。

任意のエラーメッセージを扱う

 さて、ここまでの解説では、エラーメッセージを定義する場所も受け取る場所もありませんでした。エラーメッセージを受け取りたい場合は、isValid()の代わりにvalidate()を使います(リスト4)。

[リスト3]Yup単独でバリデーションを実行する
schema
  .validate({
    name: 'Taro',
    age: 'hi', // 数値型ではなく文字列型を渡している
  })
  .then(function (value) { // (1)
    // ...
  })
  .catch(function (err) { // (2)
    console.log(err.errors); // => ['age must be a number']
  });

 validate()を使った場合は、isValidのときと比べて挙動が変わります。成功した場合である(1)の.then()には、検証対象だった値(validate()の第一引数)がそのまま渡されます。一方、失敗した場合である(2)の.catch()には、エラーメッセージの配列が渡されます。ようやくここでエラーメッセージを見ることができました。

 エラーメッセージが英語で記載されているのが気になりますが、これはカスタマイズできます。スキーマを定義する時点で、各条件の関数に引数として文字列を渡すと、バリデーションエラーが起きたときにエラーメッセージとして利用されるのです(リスト4)。

[リスト4]エラーメッセージをカスタマイズする
import * as yup from 'yup';

const schema = yup.object().shape({
  name: yup.string().required('名前は必須項目です'),
  age: yup.number('年齢は数値で入力してください') // (1)
    .required('年齢は必須項目です')
    .positive('正の数を指定してください')
    .integer('整数で指定してください'),
  email: yup.string().email('メールアドレスの形式が不正です'),
});

schema
  .validate({
    name: 'Taro',
    age: 'hi', // 数値型ではなく文字列型を渡している
  })
  .catch(function (err) {
    console.log(err.errors); // => ['年齢は数値で入力してください'] // (2)
  });

 リスト2のスキーマ定義に少し手を加えて、各条件にメッセージを登録しました。(1)でageが数値ではなかった場合のメッセージを登録しています。これはリスト3の例と同様にエラーになり、(2)には(1)と同じ文字列がエラーメッセージとして渡されてきます。このように、日本語のエラーメッセージを扱うことも可能です。

 エラーメッセージを登録し忘れると、画面に英語のメッセージが出てくることになるので、業務で利用する場合には注意が必要かもしれません。


  • LINEで送る
  • このエントリーをはてなブックマークに追加

あなたにオススメ

著者プロフィール

  • WINGSプロジェクト 中川幸哉(ナカガワユキヤ)

    <WINGSプロジェクトについて> 有限会社 WINGSプロジェクトが運営する、テクニカル執筆コミュニティ(代表 山田祥寛)。主にWeb開発分野の書籍/記事執筆、翻訳、講演等を幅広く手がける。2018年11月時点での登録メンバは55名で、現在も執筆メンバを募集中。興味のある方は、どしどし応募頂...

  • 山田 祥寛(ヤマダ ヨシヒロ)

    静岡県榛原町生まれ。一橋大学経済学部卒業後、NECにてシステム企画業務に携わるが、2003年4月に念願かなってフリーライターに転身。Microsoft MVP for ASP/ASP.NET。執筆コミュニティ「WINGSプロジェクト」代表。 主な著書に「入門シリーズ(サーバサイドAjax/XM...

バックナンバー

連載:現場で役立つ! React向けライブラリ詳説
All contents copyright © 2005-2021 Shoeisha Co., Ltd. All rights reserved. ver.1.5