これは「react-jsonschema-formのカレンダー | Advent Calendar 2023 - Qiita」の19日目の記事です。
react-jsonschema-form (RJSF) にはいくつかのユーティリティ的な関数が含まれています。
RJSF utility functions, constants and types | react-jsonschema-form
それらの関数は、大きく分けると
- Non-Validator utility functions
- Validator-based utility functions
- Schema utils creation function
の種類があります。
今回は Non-Validator utility functions のうち、主にデータを変換する系のユーティリティ関数を見ていきます。
目次
- 環境
- データの型を推測する guessType()
- 文字列を DateObject へと変換する parseDateString()
- DateObject を文字列にする toDateString()
- ローカル時刻文字列をUTC文字列にする localToUTC()
- UTC文字列をローカル時刻文字列にする utcToLocal()
- 先頭ゼロ詰めする pad()
- 数値化する関数 asNumber()
- ソースコード
環境
- react-jsonschema-form 5.15.0
- React 18.2.0
- React Router 6.20.1
なお、今回は
- string型で日付フォーマットの入力項目
- integer型の入力項目
- string型の入力項目(フォーマット指定なし)
を持ったフォームの onSubmit の「ここに追加する」の場所にて、調査対象の関数を実行し挙動を確認します。
import {asNumber, guessType, localToUTC, pad, parseDateString, RJSFSchema, toDateString, utcToLocal} from "@rjsf/utils"; import Form from "@rjsf/mui"; // MUI version import validator from "@rjsf/validator-ajv8"; export const TransformationFunctionForm = () => { const schema: RJSFSchema = { title: "Transformation Function", type: "object", properties: { datetimeInput: { type: "string", format: "date-time", default: "2023-12-19 00:00:00" }, integerInput: { type: "integer" }, stringInput: { type: "string" } } } // 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> ) }
データの型を推測する guessType()
データの型を推測する場合、 typeof だったり、オブジェクトの [[Class]] を用いた判定だったりが使えます。
JavaScriptの「型」の判定について #JavaScript - Qiita
また、RJSFの場合は guessType() 関数も使えます。
guessType() | RJSF utility functions, constants and types | react-jsonschema-form
そこで、 [[Class]] と guessType() ではどのように違うのかをためしてみます。
まず [[Class]] の結果は以下の通りでした。
const toString = Object.prototype.toString console.log(toString.call(formData.datetimeInput)) // => [object String] console.log(toString.call(formData.integerInput)) // => [object Number] console.log(toString.call(new Date())) // => [object Date]
一方、guessType の結果は以下の通りでした。
Date オブジェクトの場合はnumber型とみなしたようです。JSON Schemaには日付がないことから、これでも問題ないのかもしれません。
console.log(guessType(formData.datetimeInput)) // => string console.log(guessType(formData.integerInput)) // => number console.log(guessType(new Date())) // => number
文字列を DateObject へと変換する parseDateString()
RJSFで type="string" かつ format="date-time" の場合、見た目が日時の入力になります。
また、 formData で受け取ったときの値は文字列になります。
const toString = Object.prototype.toString console.log(toString.call(formData.datetimeInput)) // => [object String]
そのため、入力値を日付として扱いたい場合、 parseDateString() 関数を使うと便利です。
parseDateString() | RJSF utility functions, constants and types | react-jsonschema-form
なお、この関数の戻り値は DateObject 型であり、JavaScriptの Date とは異なります。
ためしに型を判定させてみると、Date ではなく Object になります。
console.log(toString.call(new Date())) // => [object Date] console.log(toString.call(parseDateString(formData.datetimeInput, true))) // => [[object Object]]
なお、第2引数の includeTime に boolean を渡すことで、時刻の設定有無を変更します。
console.log(parseDateString(formData.datetimeInput, false)) // 時刻なし console.log(parseDateString(formData.datetimeInput, true)) // 時刻あり
変換後の値をコンソールで確認すると以下の結果になりました。
DateObject を文字列にする toDateString()
parseDateString と逆の動きをするのが toDateString 関数です。
toDateString() | RJSF utility functions, constants and types | react-jsonschema-form
こちらも第2引数 time に boolean を渡すことで、時刻を含む・含まないの切り替えができます。
const dateObject = parseDateString(formData.datetimeInput, true) console.log(toDateString(dateObject, false)) // 時刻なし console.log(toDateString(dateObject, true)) // 時刻あり
コンソールへの出力は以下でした。
ローカル時刻文字列をUTC文字列にする localToUTC()
日付への変換ではなく、ローカル時刻からUTCへと文字列のまま変換するのが localToUTC() 関数です。
RJSF utility functions, constants and types | react-jsonschema-form
なお、この関数の引数は元となる日時の文字列だけであり、タイムゾーンなどは渡せません。
console.log(formData.datetimeInput) // => 2023-12-19 00:00:00 console.log(localToUTC(formData.datetimeInput)) // => 2023-12-18T15:00:00.000Z
UTC文字列をローカル時刻文字列にする utcToLocal()
localToUTC とは逆の関数が utcToLocal になります。
utcToLocal() | RJSF utility functions, constants and types | react-jsonschema-form
なお、 utcToLocal 関数も引数としてタイムゾーンを受け取ることができません。
また、フォームから入力したデータをそのまま渡すと変換できず、末尾にUTCを表す Z が必要です。
console.log(utcToLocal(formData.datetimeInput)) // => 2023-12-19T00:00:00.000 connsole.log(utcToLocal(`${formData.datetimeInput}Z`)) // 末尾に "Z" を付与してUTC化 // => 2023-12-19T09:00:00.000
先頭ゼロ詰めする pad()
入力値に対して先頭ゼロ詰めしたい場合は pad() 関数が使えます。
pad() | RJSF utility functions, constants and types | react-jsonschema-form
pad 関数の桁数に届かない場合はゼロ詰めを、超過したり undefined を渡すとそのまま返ってきます。
console.log(pad(formData.integerInput, 4)) // 3を入力 => 0003 // 30000を入力 => 30000 // undefinedのまま => undefined
数値化する関数 asNumber()
入力値に応じて数値化する関数 asNumber() もあります。
asNumber() | RJSF utility functions, constants and types | react-jsonschema-form
.1 と 1. と 1.2 を渡した時のそれぞれの挙動を見てみます。
console.log(asNumber(formData.stringInput)) // .1 を入力 => 0.1 // 1. を入力 => 1. // 1.2 を入力 => 1.2
ソースコード
Githubにあげました。
https://github.com/thinkAmi-sandbox/rjsf_advent_calendar_2023
今回のプルリクはこちら。
https://github.com/thinkAmi-sandbox/rjsf_advent_calendar_2023/pull/17


