Closed12

React-Hook-Form 学びメモ

yutaro.matsumotoyutaro.matsumoto

Controlled Component とUncontrolled Component

以下の認識。

  • Controlled Componentはformの値をstateで管理。
  • Uncontrolled Componentsはformの値をDOMで管理。

ただ、ReactはControlldedを推奨していて、これはReactが生まれた歴史から考えても当然のように思える。
自分が使うとしても基本的にControlled Componentを利用する。
https://reactjs.org/docs/uncontrolled-components.html

yutaro.matsumotoyutaro.matsumoto

ref属性が必要な時

https://ja.reactjs.org/docs/refs-and-the-dom.html#when-to-use-refs
例えば、Componentでfocusの管理をしたいときなどに、どうしてもrefが必要になる。
React Hook FormでいうとsetFocusなどを使いときなど。
refとは、DOMにアクセスするための機能?
意外とこの辺りについては調べても詳細が中々出てこなかったが、DOMを参照したいときに使うとのこと。
DOM側のみで管理されている情報を参照したいときに使うものだとイメージしている。

nap5nap5

Componentでfocusの管理をしたいときなどに、どうしてもrefが必要

RHFのController経由で取得できるrefを使ったフォーカスのデモを作ってみました

以下の部分がFocusする実装になります

この実装があると、アイテム追加するたびに、入力フィールドへフォーカスが自動であたるようになります

また、Submit時にバリデーションエラーがあると、バリデーションエラーが起きている先頭の入力フィールドへフォーカスがあたるようになります

<Input
  {...omit(field, ["ref"])}
  /**
   * @see https://codesandbox.io/p/sandbox/react-hook-form-with-mui-one-time-password-input-forked-eb61t2?file=%2Fsrc%2Findex.js%3A30%2C13-35%2C17
   *
   * @see https://github.com/orgs/react-hook-form/discussions/10167#discussioncomment-5430386
   */
  ref={(elem: HTMLInputElement) => {
    field.ref({
      ...elem,
      focus: () => elem.querySelector("input")?.focus(),
    });
  }}
  type="text"
  placeholder="劇場版SHIROBAKO"
  sx={(theme) => ({
    "--variant-borderWidth": "2px",
    ...(errorInfo != null && {
      "--variant-borderWidth": "2px",
      "--variant-outlinedBorder": theme.palette.danger[500],
      "&.MuiInput-root:before": {
        "--Input-focusedHighlight": theme.palette.danger[500],
      },
    }),
  })}
/>;
yutaro.matsumotoyutaro.matsumoto

useFormContext

この辺りについて調べる。

  • useFormContextにはuseFormのようにFormの型を渡せるが、これは具体的にどんなメリットがあるのか。
  • Pathについて
yutaro.matsumotoyutaro.matsumoto

Controllerを利用する場合のcontrol Propsを利用するメリットについて

正直これがよくわからない。

useFormのcontrolは↓こんな説明が。

This object contains methods for registering components into React Hook Form.

Controllerを利用するということは、ラッピングするfieldはControlled Componentになる認識。
controlを利用するメリット、利用することで変化することは?
公式でもControllerのcontrolにuserFormのcontrolを渡しているのはなぜか不明。

yutaro.matsumotoyutaro.matsumoto

FormProviderを使っていたからオプショナルになっていて、メリットを感じられなかったが、FormProviderを利用しない場合は利用しないとエラーになる。

yutaro.matsumotoyutaro.matsumoto

ソース見れてないけどformのcontextがあって、それにfieldを登録・アクセス・するために必要ってことなのかな。

yutaro.matsumotoyutaro.matsumoto

ControllerのdefaultValue

useFormのdefaultValuesとControllerのdefaultValueどちらも設定している場合、useFormで設定したdefaultValueが優先される。

yutaro.matsumotoyutaro.matsumoto

基本的にはuseFormでdefaultValueを設定してあげた方が、子コンポーネント側にとっても良いことな気がする。
子コンポーネント内でuseWatchやgetValueを利用する際、レンダリングのタイミングを特に気にしなくて済む。子コンポーネント内で、自身が持つfieldのvalueを取得した時とかもその方が余計なことをしなくて済む。

yutaro.matsumotoyutaro.matsumoto

ネストされたComponent内でfieldのvalueを取得したいとき

子コンポーネント内で自身がもつfieldのvalueを取得し、その結果から出力を分岐させたい時もあると思う。
その場合は、useWatchでdefaultValueを渡してあげるとかの選択になるのか?

yutaro.matsumotoyutaro.matsumoto

useFormで設定したdefaultValuesなら、問題なく子コンポーネント内でも取得できる。
やっぱりRHFでformにデフォルトで値を入れたいときは、useFormのdefaultValuesで設定してあげるのが一番良い気がする。

このスクラップは2023/12/04にクローズされました