🐥

react-hook-formハマりポイント② 🖍️registerが機能しない?ComponentPropsとrefについて

2023/08/29に公開

はじめに

react-hook-formを使っていて、ハマったポイントがいくつかあったのでまとめていきます。

※本記事では、reack-hook-formの説明は省きます。

その①

今回は、ComponentPropsを使用したコンポーネントへuseFormregisterを渡す時のお話です。

ハマった点

前述の通り、ComponentPropsを使用して作成した入力コンポーネントに、HTML要素にregisterを渡すのと同様に記述したのですが、入力値が参照できず・・・🤔

  • ComponentPropsを使用してコンポーネントInputを作成
type InputProps = ComponentPropsWithRef<'input'>;

export const Input: FC<InputProps> = ({ ...props }, ref) => {
・・・
  • Inputregisterを渡す
    <Input
        {...register('password')}
    />

ComponentPropsとは

HTML要素をカスタマイズしてコンポーネント化して使用することがよくあると思いますが、そのときに便利なのがComponentPropsです。
ComponentPropsを用いて型を定義することで、Reactの提供するElementが持つデフォルトのpropsを全て受け取れるようになります。

  • 分割代入で全ての値を渡すことができる
  • {...props} の下に特定のpropsを記述すると独自の振る舞いになる。
import { ComponentPropsWithRef, FC } from 'react';

type InputProps = ComponentPropsWithRef<'input'>;

export const Input: FC<InputProps> = ({ ...props }, ref) => {
    return (
        <input
            {...props}
            className={'rounded border-2 px-4 py-2 text-sm' + props.className}
            ref={ref}
        />
    );
};

Refの許容を明示的に示す

refを許容したい場合はComponentPropsWithRefを使う必要があります。
許容したくない場合はComponentPropsWithoutRefを使用します。

そもそもRefとは

ref はstate と同様に、文字列、オブジェクト、さらには関数など、あらゆるものを指すことができます。
stateとは異なり、refは読み取り及び変更できるcurrentプロパティを持つ、プレーンなJavaScriptオブジェクトです。

https://react.dev/learn/referencing-values-with-refs

解決方法

forwardRefにてrefを子コンポーネントに転送する

Reactでは親コンポーネントが子コンポーネントのrefに直接アクセスできないため、フォワーディングの必要があるようでした。

このforwardRefを使用して、先程のコンポーネントを修正してみます。

import { ComponentPropsWithRef, forwardRef, FC } from 'react';

type InputProps = ComponentPropsWithRef<'input'>;

export const Input: FC<InputProps> = forwardRef(({ ...props }, ref) => {
    return (
        <input
            {...props}
            className={'rounded border-2 px-4 py-2 text-sm' + props.className}
            ref={ref}
        />
    );
});

これで、無事にregister使用して値の参照ができるようになりました✨✨

https://react.dev/reference/react/forwardRef

さいごに

普段あまり意識せずrefを使っていましたが、react-hook-formをきっかけにコンポーネント間における作用について学びになりました。
少しでも、同様に詰まった方の助けになれば幸いです。

それでは、読んでいただきありがとうございました。

エックスポイントワン技術ブログ

Discussion