Shuhei
ReactHookFormのforwardRefについて
2026年05月09日
見出しはありません
要約を生成中...
React18以前のバージョンで本件の考慮が必要。React19以降は...register内にrefが含まれるため考慮不要。
RHFを用いたフォームの実装で、Reactのコンポーネント分割の際に留意したことをナレッジとして記録します。
例えばこんなフォームUI
<form>
<div>
<Label htmlFor="email" children="メールアドレス" />
<Input
{...register("email", { required: "メールアドレスは必須です。" })}
type="email"
disabled={isSubmitting}
placeholder="name@company.com"
data-auth-ext-processed="true"
/>
<p className="text-red-600">{errors.email?.message}</p>
</div>
</form>
Inputコンポーネント
import { type ComponentProps } from "react";
export const Input = (props: ComponentProps<"input">) => {
return (
<input
{...props}
className="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5"
data-auth-ext-processed="true"
/>
);
};...register はRHFのuseFormからインポートしています。このregisterの中身は
// {...register("email")} の中身
name: "email",
onChange: (e) => { /* バリデーションとか */ },
onBlur: (e) => { /* フォーカス外した時の処理 */ },
ref: (instance) => { /* DOM要素を登録する関数 */ }ref も入っているのですが、こいつだけReactの中で別枠でpropsとして受け取ってくれないです
ref はRHFがフォーム送信時に各inputの値を見に行くときのパイプみたいなもの必ず指定が必要。
「ref もちゃんと中にある input タグに届けてね」と明示的に設定する方法。
"use client";
import { forwardRef, type ComponentProps } from "react";
// forwardRef で囲むことで、親からのrefを第二引数で受け取れるようになる
export const Input = forwardRef<HTMLInputElement, ComponentProps<"input">>(
(props, ref) => {
return (
<input
{...props}
ref={ref} // ← これが超重要!ここで初めてRHFとDOMが繋がる
className="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5"
/>
);
}
);
// コンポーネントに名前をつけておくとデバッグしやすい(forwardRefを使う際の推奨)
Input.displayName = "Input";冒頭にも記載しましたが本件の内容はReact18以前の内容です。React19以降ではrefをわざわざ記述しなくても標準装備されていて、fowardRefは非推奨になっています。(ref使わない場面なさそうだからこれは普通にナイス)
ただ、refってなんぞや?を考えるいいきっかけになったので書いてみました。
ReactHookFormはなかなか奥が深くて、おもしろいです。実務でごりごり使えるとつよつよエンジニアになれそうなのでわたしも頑張ります〜😌
コメント
まだコメントはありません。