react-jsonschema-formにて、JSON Schemaのdefinitionsや外部JSONファイルを使ったときの表示を確認してみた

これは「react-jsonschema-formのカレンダー | Advent Calendar 2023 - Qiita」の4日目の記事です。

この記事では、react-jsonschema-formにて

  • JSON Schemaの 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
  • $id
    • 今回は適当なURL https://example.com/thinkami.json にする

 
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ではそのような方法はサポートしてなさそうです。

 
そのため、

のどちらかで実装する必要がありそうです。

 

ソースコード

Githubにあげました。
https://github.com/thinkAmi-sandbox/rjsf_advent_calendar_2023

今回のプルリクはこちら。
https://github.com/thinkAmi-sandbox/rjsf_advent_calendar_2023/pull/3