Reactアプリケーションにおけるフォーム開発では、バリデーションロジックの肥大化が課題になりがちです。react-jsonschema-form (RJSF)を採用することで、JSON Schemaに基づいた宣言的なフォーム構成とバリデーション定義が可能になります。本記事では、RJSFを用いた入力制限の実装方法を解説します。
react-jsonschema-formの主な特徴
RJSFは、データ構造を定義するJSON SchemaからReactフォームを自動生成するライブラリです。コードベースのバリデーションを削減し、スキーマ定義に集中できるのが最大の利点です。
- スキーマ駆動: JSON Schema標準に準拠したバリデーション。
- テーマ対応: Material UI、Ant Design、Bootstrapなどの主要UIライブラリをサポート。
- 柔軟な拡張性: カスタムウィジェットや独自のバリデーションロジックの統合が可能。
導入と基本構成
まずは必要なパッケージをインストールします。ここではコアライブラリとMaterial UIテーマを例にします。
npm install @rjsf/core @rjsf/utils @rjsf/validator-ajv8 @rjsf/mui
次に、基本的なスキーマとコンポーネントを定義します。以下の例では、ユーザーのプロフィール登録フォームを作成しています。
import Form from '@rjsf/mui';
import validator from '@rjsf/validator-ajv8';
const profileSchema = {
title: "プロフィール設定",
type: "object",
required: ["userName", "accountEmail"],
properties: {
userName: {
type: "string",
title: "ユーザー名",
minLength: 3
},
accountEmail: {
type: "string",
title: "メールアドレス",
format: "email"
},
age: {
type: "integer",
title: "年齢",
minimum: 0,
maximum: 150
}
}
};
const ProfileForm = () => {
const handleProcess = ({ formData }) => {
console.log("送信データ:", formData);
};
return (
<Form
schema={profileSchema}
validator={validator}
onSubmit={handleProcess}
/>
);
};
主要な入力制限の実装パターン
1. 必須項目と文字列の長さ
required配列で必須フィールドを指定し、minLengthやmaxLengthで文字数を制御します。
{
"type": "object",
"required": ["identifier"],
"properties": {
"identifier": {
"type": "string",
"minLength": 5,
"maxLength": 15
}
}
}
2. 数値の範囲制限
数値入力に対しては、minimum、maximum、およびmultipleOfを使用して制限をかけます。
{
"points": {
"type": "number",
"title": "スコア",
"minimum": 0,
"maximum": 100,
"multipleOf": 0.5
}
}
3. 正規表現によるパターンマッチ
特定のフォーマット(電話番号や特定のコード体系など)を強制する場合、pattern属性に正規表現を記述します。
{
"postalCode": {
"type": "string",
"title": "郵便番号",
"pattern": "^\\d{3}-\\d{4}$"
}
}
高度なバリデーション機能
フィールド間の依存関係
特定の選択肢が選ばれた時のみ、別の入力項目を必須にする、あるいは表示するといった制御はdependenciesを使用します。
{
"type": "object",
"properties": {
"contactMethod": {
"type": "string",
"enum": ["None", "Phone"],
"default": "None"
}
},
"dependencies": {
"contactMethod": {
"oneOf": [
{
"properties": {
"contactMethod": { "enum": ["None"] }
}
},
{
"properties": {
"contactMethod": { "enum": ["Phone"] },
"phoneNumber": { "type": "string", "pattern": "^[0-9]+$" }
},
"required": ["phoneNumber"]
}
]
}
}
}
カスタムエラーメッセージの適用
デフォルトのエラーメッセージを日本語化したり、より具体的な内容に変更したい場合は、transformErrorsプロップを利用します。
const customTransform = (errors) => {
return errors.map(error => {
if (error.name === "minLength") {
error.message = `${error.params.limit}文字以上で入力してください`;
}
return error;
});
};
// コンポーネント側
<Form
schema={schema}
validator={validator}
transformErrors={customTransform}
/>
リアルタイムバリデーション
送信ボタンを押す前、入力のたびに検証を行いたい場合はliveValidateオプションを有効にします。
<Form
schema={schema}
validator={validator}
liveValidate={true}
/>
react-jsonschema-formを利用することで、複雑なバリデーションルールもスキーマ定義として一元管理でき、メンテナンス性の高いフォーム実装が可能になります。