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