What should the default form library be in Blitz apps?
BlitzがどのFormライブラリをデフォルトにするかの議論が参考になったので要約しました。
の3択で,結論としては,React Final Formを推奨とする形に落ち着きました。
最初のコメント
Blitz.jsの作者であるBrandon(@flybayer)さんがコメントしています。要約するとこんな感じ。
-
Formik
以前使ってたけど,パフォーマンスめっちゃ悪いって気づいたから,Formikは無しで。 -
React-final-form
最近ずっと使ってるけどいい感じ。 -
React-hook-form
ほとんど使ったことない。
React-final-formをReact-hook-formに書き換えてみたが,コードの複雑さとしてはそこまで差異はない。
https://github.com/blitz-js/blitz/pull/767/files
議論
全体的にFormikは無いよねという感じでした。
気になった意見をpick upします。
react-hook-formのデメリット
対象のコメント→ https://github.com/blitz-js/blitz/discussions/768#discussioncomment-39148
別のFormライブラリとの互換性の低さ
MaterialUIなどのサードパーティー製のコンポーネントと一緒に使う場合は
<Controller>
コンポーネントでwrapしなくてはいけない。
<Controller
name="iceCreamType"
as={Select}
options={[
{ value: "chocolate", label: "Chocolate" },
{ value: "strawberry", label: "Strawberry" },
{ value: "vanilla", label: "Vanilla" }
]}
control={control}
rules={{ required: true }}
/>
<Controller>
を使わないパターンと使うパターンの2つの異なるAPIを知っておかなくてはいけない。
一方,react-final-formはuseField()
というAPIだけで済むので,他のライブラリとの互換性が高い。
refの渡し方が不自然
focusしたときに何かを発動したいときなどはrefを自分で渡すことになるが,そのときのrefの渡し方が面倒くさい。
const { register, handleSubmit } = useForm();
const firstNameRef = useRef();
const onSubmit = data => console.log(data);
return (
<form onSubmit={handleSubmit(onSubmit)}>
<input name="firstName" ref={(e) => {
register(e) // hook-form register
firstNameRef.current = e // manually assign your ref
}} />
ref={ref}
で渡したいのに…。
react-final-formのデメリット
render propsが初心者には難しいのではないか?というコメントがいくつかあった。
- 基本的にrender propsを使う
- react-final-form
- formik
- 基本的にrender propsを使わない
- react-hook-form
それに対し,Brandonさんは以下のように反論しています。
there is only one top level render prop with final-form which also provides the form context.
トップ層でしか使用していないし,
So either way, you'll likely have a render prop. I definitely agree the primary API shouldn't be a render prop, but looks like it's impossible to 100% avoid render props.
react-hook-formでも<Controller/>
を使ったらrender propsを使うことになるし,render propsから完全に逃れることはできないのではないか?とのことです。
まとめ
今回はReact Final Formを推奨とする結論になりましたが,「とにかく速く開発したいからみんなが使えて学習コストの低いreact hook formで」など,プロジェクトによって吟味する必要がありそうです。
「react-hook-formは広く使われているからみんな慣れてるだろうし良い」というような意見に対して「学習コストが低いものを選定基準にするのではなく,既存のプロジェクトをBlitzに置き換えることになったときになるべく痛みが少ないものを使いたい。」と返していて,ライブラリ選定の参考になる見方だと思いました。
追記
React Hook Formの作者である@bluebill1049さんがコメントしてくださりました。(詳しくは本人のコメントを参照してください!)
2020年12月ごろにリリースされたv6.13.0でuseController
というhooksが追加されました。それを使えば<Controller>
で囲ってRender prop
を使うという必要がなくなります。Material UIのコンポーネントなどを使う場合は<Controller>
を使うしかありませんが,自作のコンポーネントを使う場合はuseController
が使えます!
また,ref
についてもV7ではフォーカス管理を改善していく予定とのことです。