これは「react-jsonschema-formのカレンダー | Advent Calendar 2023 - Qiita」の12日目の記事です。
react-jsonschema-form (RJSF) では、フォームの入力値に対するvalidatorとして ajv
を使います。
Validation | react-jsonschema-form
ajv
には複数のオプションがあり、実行時の挙動を変更できます。
Ajv options | Ajv JSON schema validator
そこで、RJSFでも ajv
のオプションを設定・利用できるかためしてみます。
目次
環境
- react-jsonschema-form 5.15.0
- React 18.2.0
- React Router 6.20.1
RJSFでajvのオプションを変更する
RJFSからajvのオプションを変更する方法は、以下の公式ドキュメントに記載されています。
ajvOptionsOverrides | Validation | react-jsonschema-form
そこで、以下のようにオプションを変更してみます。
allErrors
をtrue
にする- https://ajv.js.org/options.html#allerrors
- 1つの項目に対する複数のエラーメッセージを表示する
$comment
をtrue
にする- https://ajv.js.org/options.html#comment
- JSON Schemaの
$comment
をコンソール表示する
まず、オプションが有効になっているか確認できるよう、JSON Schemaを
$comment
を定義- 1つの項目に対して
minLength
とpattern
を定義
とします。
なお、patternについては、Understanding JSON Schemaのページのものを使っています。
JSON Schema - Regular Expressions
const schema: RJSFSchema = { title: "Additional Ajx Option Form", type: "object", $comment: "my comment", properties: { stringInput: { type: "string", minLength: 5, pattern: "^(\\([0-9]{3}\\))?[0-9]{3}-[0-9]{4}$" } } }
続いて、ajvのオプションを定義したオブジェクトを customizeValidator
の引数として渡してvalidatorを生成し、それをFormのpropsとして渡します。
なお、公式ドキュメントの渡し方だとうまく動作しなかったため、以下のような実装としています。
const options: CustomValidatorOptionsType = { ajvOptionsOverrides: { // https://ajv.js.org/options.html#allerrors allErrors: true, // https://ajv.js.org/options.html#comment $comment: true, } } const validator = customizeValidator(options) return ( <div style={{width: '400px'}}> <Form schema={schema} validator={validator} /> </div> )
動かしてみたところ、
- 1つの項目に対する複数のエラーメッセージを表示する
- JSON Schemaの
$comment
をコンソール表示する
が実現できていました。
ajvがサポートするJSON Schemaバージョンを差し替える
RJSFでは、 customValidator
関数に AjvClass
を渡すことで、バリデーションの元となるJSON Schemaのバージョンを切り替えられます。
AjvClass | Validation | react-jsonschema-form
ただ、
- RJSFがJSON Schema
draft-7
対応なので、RJSFSchema
型のschemaで定義すると型エラーになる- 例えば、draft 2019-09より追加された
minContains: 1
を指定するとエラー- https://json-schema.org/draft/2019-09/release-notes#validation-vocabulary
Initializer type {title: string, type: "object", properties: {arayInput: {type: "array", items: {type: "object", properties: {stringInput: {type: ...}, integerInput: {type: ...}}}, minContains: number}}} is not assignable to variable type RJSFSchema
- 例えば、draft 2019-09より追加された
- ajvは
draft-7
時点でも、draft 2019-09
で追加されたフォーマットduration
やuuid
に対応済 ajv-formats
はidn-hostname
などを扱えず、draft 2019-09 に完全対応しているわけではない- プラグイン
ajv-formats-draft2019
を使えば扱える
- プラグイン
より、 AjvClass
を差し替えても...という感じです。
ソースコード
Githubにあげました。
https://github.com/thinkAmi-sandbox/rjsf_advent_calendar_2023
今回のプルリクはこちら。
https://github.com/thinkAmi-sandbox/rjsf_advent_calendar_2023/pull/11