react-hook-formでregisterとControllerのどちらを使うか
react-hook-formでのFormの作り方には2つ方法がある
useFormのregisterを使って、<input {...register('hoge')} />とする
useFormのcontrolとRHFのControllerを使って、<Controller ../>とする
そもそも、Reactのfieldを定義する方針としては2種類ある
Uncontrolled Components
素の<input/>など
これは、rhfと併用する場合、registerと<Controller/>の両方で使用できる
Controlled Components
MUIなど、外部のUI libraryが提供するfieldとか
React Nativeが提供する<TextInput />とか
これは、rhfと併用する場合、<Controller/>を使う以外に方法はない
registerは、Uncontrolled Componentsものとしてfieldを定義する
そのため、入力時にも無駄な再renderingが生じない
<Controller/>は、Controlled Componentsとしてfieldを定義する
そのため、fieldを定義している箇所は再renderingが生じる
方針
基本的に、registerを使う
registerが使えない場合は、<Controller/>を使う
パフォーマンスの観点
再rendering回数の比較をした
コードはこちら
fieldになにか入力して、console.logを見れば確認できる
fieldとしては、以下のいずれかをつかっている
素の<input/>
自作Uncontroleld Componentである<Input/>
以下の4つを比較した
register + 素のinput
re-renderingしない
register + <Input/>
re-renderingしない
Controller + <Input/>
<Input/>の箇所だけre-rendering
useController + <Input/>
useControllerを使っている箇所も、<Input/>もre-rendering
パフォーマンス的にはこれが最も悪い
react-hook-formにできるだけ依存させない観点
これは別にどちらを使っても大きな違いはない
rhfに依存させない対象のComponentが、
Controlled Componentsなら、<Controller/>を使うしかなく、
そうでないなら、registerを使えば良い
上に書いている方針と同じ
react-hook-formに依存しないInput Componentを用意すれば良い
useControllerを使ってラップするComponentを定義する解説記事を見かけるが、
パフォーマンス的にも良くないし、わざわざ用意する理由がわからんmrsekut.icon
この辺の記事
project全体でのinterfaceを統一させたい観点
使用するfieldは、Controlledだったり、Uncontrolledだったりするので、
原理的には、
registerに統一する、は無理だけど
<Controller/>に統一する、はできる
しかし、Controllerの方に統一すると、せっかくのUncontrolled Componentsも全てControlledにすることになる
パフォーマンス的に勿体ない
interfaceの差はそこまで難しいわけでもないので、統一しなくて良くない?と思う