Reactのフォーム、バリデーションライブラリの比較

Reactフォームライブラリの比較

  • react-redux-form: 状態管理にreduxを利用していないため除外
  • formic: 再レンダリングパフォーマンスが悪いらしいため除外
  • react-final-form
  • react-hook-form

react-final-form vs react-hook-form

react-final-form, react-hook-formを比較する。

react-final-form

  • 3.2kb (+ final-form 5.2kb)
  • ts型ビルトイン
  • Blitz.jsで採用されている。
  • name, value, handlerなどをコンポーネントに渡す形式
ドキュメント
chakrauiとの併用サンプル
hooksもある

react-hook-form

  • 8.2KB
  • ts型ビルトイン
  • react-final-formより人気
  • ドキュメントが見やすい、日本語記事も見つかりやすい
  • 最大/最小値、必須、正規表現などもビルトインでできる
  • refをコンポーネントに渡す形式
ドキュメント
chakrauiとの併用サンプル
外部ライブラリのコンポーネント、自作コンポーネントはrefを渡せるようにする必要がある。 自作の場合は React.forwardRef で対応できる。

結論

どちらも出来ることに差はなさそう

react-hook-formはrefを渡すインターフェースが特徴的で、react-final-formの方がシンプルに見える。 ドキュメントが充実していて、日本語記事も多いためreact-hook-formを選んでおくのが無難そうではある。

バリデーションライブラリの比較

バリデーションライブラリの比較をする。 シンプルなAPIのものを利用して複雑なバリデーションは自作する方針にしたい。

参考記事
とりあえず沢山あることが分かった..

下記がメジャーで日本語記事もよく見つかる。

  • yup
  • zod

yup vs zod

yupとzodを比較する。 zodのREADME.mdに比較内容が記載されている。

yup

  • 18.2kb
  • デフォルト任意入力
  • APIの差分
    • nubmer.round
    • object.camelCase
    • string.trim
    • cast, transform
API

zod

  • 11.3kb
  • デフォルト必須入力
  • APIの差分
    • object.partial, object.deepPartial
    • union, intersection
    • primise
    • function
  • Blitz.jsで採用されている (final-form x zod)
API
Blitz.js
yupは途中からzodは最初からtypescriptに対応していたという経緯があるからか、下記の記事に書かれているように型生成時の挙動が安定していない部分があるらしい。
react-hook-formと組み合わせる場合、zodでnumberを扱う時に { valueAsNumber: true } のような記載をする必要がある。 scheme自体はyupよりzodの方がシンプルに見える。

結論

ユーザ数はyupが圧倒的に多いため困った時に助かりそうだが、Blitz.jsが採用している & typescriptフレンドリーなzodを利用してみたいと思った。

余談

Ant Designはビルトインで Form コンポーネントにtypescript対応のstate管理とバリデーションが付いている。
  • ステート管理 useForm
  • バリデーション
async-validatorという薄い(4.5kb)ライブラリが利用されていた。

Ant Designを利用する場合はreact-hook-form, zodを利用せず、ビルトインのシンプルなAPIで頑張れそうだと思った。