これは「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
