Reactのフォーム、バリデーションライブラリの比較
Reactのフォームライブラリを比較する。
- react-redux-form: 状態管理にreduxを利用していないため除外
- formic: 再レンダリングパフォーマンスが悪いらしいため除外
- react-final-form
- react-hook-form
react-final-form, react-hook-formを比較する。
react-final-form
- 3.2kb (+ final-form 5.2kb)
- ts型ビルトイン
- ドキュメント
- Blitz.jsで採用されている。
- name, value, handlerなどをコンポーネントに渡す形式
input
chakrauiとの併用サンプル
hooksもある
react-hook-form
- 8.2KB
- ts型ビルトイン
- ドキュメント
- react-final-formより人気
- ドキュメントが見やすい、日本語記事も見つかりやすい
- 最大/最小値、必須、正規表現などシンプルなバリデーションもビルトインでできる
- refをコンポーネントに渡す形式
register
chakrauiとの併用サンプル
外部ライブラリのコンポーネント、自作コンポーネントはrefを渡せるようにする必要がある。
自作の場合は React.forwardRef
で対応できる。
結論
どちらも出来ることに差はなさそう
react-hook-formはrefを渡すインターフェースが特徴的で、react-final-formの方がシンプルに見える。
ドキュメントが充実していて、日本語記事も多いためreact-hook-formを選んでおくのが無難そうではある。
バリデーションライブラリの比較をする。
シンプルなAPIのものを利用して複雑なバリデーションは自作する方針にしたい。
参考記事
とりあえず沢山あることが分かった..
下記がメジャーで日本語記事もよく見つかる。
- yup
- zod
yupとzodを比較する。
zodのREADME.mdに比較内容が記載されている。
yup
- 18.2kb
- デフォルト任意入力
- API
- APIの差分
- nubmer.round
- object.camelCase
- string.trim
- cast, transform
zod
- 11.3kb
- デフォルト必須入力
- API
- APIの差分
- object.partial, object.deepPartial
- union, intersection
- primise
- function
- Blitz.jsで採用されている (final-form x zod)
https://blitzjs.com/docs/utilities
yupは途中からzodは最初からtypescriptに対応していたという経緯があるからか、下記の記事に書かれているように型生成時の挙動が安定していない部分があるらしい。
react-hook-formと組み合わせる場合、zodでnumberを扱う時に { valueAsNumber: true }
のような記載をする必要がある。
scheme自体はyupよりzodの方がシンプルに見える。
結論
ユーザ数はyupが圧倒的に多いため困った時に助かりそうだが、Blitz.jsが採用している & typescriptフレンドリーなzodを利用してみたいと思った。
余談
Ant Designはビルトインで Form
コンポーネントにtypescript対応のstate管理とバリデーションが付いている。
- ステート管理
useForm
https://ant.design/components/form/#components-form-demo-control-hooks - バリデーション
https://ant.design/components/form/#Rule
async-validatorという薄い(4.5kb)ライブラリが利用されていた。
https://github.com/yiminghe/async-validator
Ant Designを利用する場合はreact-hook-form, zodを利用せず、ビルトインのシンプルなAPIで頑張れそうだと思った。
後日談
toB・デスクトップ向けのsaasでantdのFORMだけで頑張った結果、痒いところに手が届かない事が理解できた。
ある程度大きなor複雑なフォームを持つプロダクトではreact hook form(rhf)を利用するのが間違いなさそう。
ref経由でdom apiを直接利用する作りのためパフォーマンスにも優しい。
例えば、巨大なフォームを分解して兄弟・親子関係にあるフォームを作った時に、値の共有方法やイベント周りのAPIがrhfは充実・洗練されている。
(フォームのライブラリということもあるため当然ではある)
また、ユーザー数も多いためググラビリティが高く複雑な処理を書いた時に困る人が少なくなる。
(マルタスタックなチームでは特に顕著)
洗練されていて予測しやすいAPIを持っている事と有名所でドキュメントが豊富な事はとても大切。