これは「react-jsonschema-formのカレンダー | Advent Calendar 2023 - Qiita」の4日目の記事です。
この記事では、react-jsonschema-formにて
を使ったときの表示を確認してみます。
目次
- 環境
- JSON Schemaのdefinitionsとは
- RJSFにて、JSON Schemaのdefinitionsを使う
- 外部JSONファイルにJSON Schemaを定義してimportする
- RJSFでは、definitionsだけ定義した外部JSONファイルを扱えない
- ソースコード
環境
- react-jsonschema-form 5.15.0
- React 18.2.0
- React Router 6.20.1
JSON Schemaのdefinitionsとは
JSON Schemaでは、 definitions
キーワードにて項目を定義し、 $refs
キーワードにてその定義を参照・利用できます。
これにより、同じ定義を何度も書かなくて済むようになっています。
RJSFにて、JSON Schemaのdefinitionsを使う
RJSFでも、JSON Schemaの definitions
をサポートしています。
Schema definitions and references | react-jsonschema-form
今回は
definitions
にてapples
を定義properties
にて$refs
を使ってapples
を参照
というJSON SchemaをRJFSで表示できるか確認してみます。
import {RJSFSchema} from "@rjsf/utils"; import Form from "@rjsf/mui"; import validator from "@rjsf/validator-ajv8"; export const InnerDefinition = () => { const schema: RJSFSchema = { title: "Inner Definition", type: "object", required: [], definitions: { // このapplesを使い回す apples: { type: 'number', oneOf: [ { const: 10, title: 'フジ' }, { const: 20, title: 'シナノゴールド' }, { const: 30, title: '奥州ロマン'} ] } }, properties: { like: { $ref: '#/definitions/apples', title: '好きなリンゴ', }, want: { $ref: '#/definitions/apples', title: '食べたいリンゴ', } } } // onSubmitの引数の説明は以下 // https://rjsf-team.github.io/react-jsonschema-form/docs/api-reference/form-props#onsubmit const onSubmit = ({formData}, _event) => { console.log(formData) } return ( <div style={{width: '400px'}}> <Form schema={schema} validator={validator} onSubmit={onSubmit} /> </div> ) }
動作を確認すると、 好きなリンゴ
と 食べたいリンゴ
の両方で同じ表示となりました。
好きなリンゴの場合
食べたいリンゴの場合
外部JSONファイルにJSON Schemaを定義してimportする
JavaScript/TypeScriptでは、外部のJSONファイルをimportできます。
そこで、外部JSONファイルにJSON Schemaを定義し、そのJSONファイルをimportしてRJSFで使えることを確認してみます。
まず、JSON Schemaを外部のJSONファイルに定義するため、JSON Schemaの規格に合わせて以下の定義を追加します。
$schema
- RJSFがサポートしているバージョンは
draft7
のため、以下で定義されているmeta-schemaのURLhttps://json-schema.org/draft-07/schema
を指定
- RJSFがサポートしているバージョンは
$id
- 今回は適当なURL
https://example.com/thinkami.json
にする
- 今回は適当なURL
JSONファイルの全体像はこんな感じで、今回はコンポーネントと同じ階層に definition.json
として置いてみました。
{ "$schema": "http://json-schema.org/draft-07/schema", "#id": "https://example.com/thinkami.json", "title": "Import JSON File", "type": "object", "required": [], "properties": { "like": { "type": "string" } } }
続いて、RJSFでJSONファイルをimportして利用します。
import Form from "@rjsf/mui"; import validator from "@rjsf/validator-ajv8"; import jsonFile from "./definition.json" export const ImportJsonSchema = () => { // onSubmitの引数の説明は以下 // https://rjsf-team.github.io/react-jsonschema-form/docs/api-reference/form-props#onsubmit const onSubmit = ({formData}, _event) => { console.log(formData) } return ( <div style={{width: '400px'}}> <Form schema={jsonFile} validator={validator} onSubmit={onSubmit} /> </div> ) }
動かしてみたところ、JSONファイルに書いたJSON Schemaの定義にて、RJSFのコンポーネントが表示されました。
RJSFでは、definitionsだけ定義した外部JSONファイルを扱えない
外部のJSONファイルを扱うことができるのであれば、
- 項目ごとにJSON Schemaにdefinitionとして用意
- それらをRJSFにimportして使う
も可能かもしれないと考えました。
しかし、現在のRJSFではそのような方法はサポートしてなさそうです。
- Definition in $ref via files · Issue #1533 · rjsf-team/react-jsonschema-form
- $ref doesn't support url · Issue #1512 · rjsf-team/react-jsonschema-form
そのため、
のどちらかで実装する必要がありそうです。
ソースコード
Githubにあげました。
https://github.com/thinkAmi-sandbox/rjsf_advent_calendar_2023
今回のプルリクはこちら。
https://github.com/thinkAmi-sandbox/rjsf_advent_calendar_2023/pull/3