Skip to content

FAQs

よくある質問と答え。

React Hook Formのパフォーマンス

パフォーマンスはこのcustom hookを作成する主な目的の一つでした。 React Hook Formでは非制御コンポーネントによってregister関数をrefで実行しています。 このアプローチにより、ユーザーからの入力や値の変更により発生する再レンダリングの量を削減しています。 コンポーネントのページへのマウントも制御されていないことによりはるかに高速になります。こちらの他のライブラリとのマウントスピードの簡単な比較をご覧下さい。


アクセス可能な入力エラーとメッセージを作成するには?

React Hook Formは非制御コンポーネントに基づいているため、アクセス可能なカスタムフォームを簡単に構築できます。

import React from "react";
import { useForm } from "react-hook-form";

export default function App() {
  const { register, handleSubmit, formState: { errors } } = useForm();
  const onSubmit = data => console.log(data);

  return (
    <form onSubmit={handleSubmit(onSubmit)}>
      <label htmlFor="firstName">First name</label>
      <input
        id="firstName"
        aria-invalid={errors.firstName ? "true" : "false"}
        {...register('firstName', { required: true })}
      />
      {errors.firstName && (
        <span role="alert">
          This field is required
        </span>
      )}

      <input type="submit" />
    </form>
  );
}

クラスコンポーネントでも使えますか?

そのままでは動作しませんが、クラスコンポーネントを包むラッパーを作成して使用することは可能です。

クラスコンポーネント内でのHooksの使用は出来ませんが、クラスコンポーネントと Hooksを使用した関数コンポーネントを単一のDOM Tree内で混在させることは可能です。 クラスコンポーネントかHooksを使用した関数コンポーネントのどちらを利用するかは、 そのコンポーネントの実装の詳細に過ぎません。長い目で見れば、 HooksはReactのコンポーネントを書く際の最初の選択肢になっていくだろうと私達は予想しています。

フォームをリセットするには?

フォームをリセットする方法は2つあります。

  • HTMLFormElement.reset()

    フォームのリセットボタンのクリックと同等の効果を持つメソッドです。 フォーム内のinput/select/checkbox要素の値のみリセットします。

  • React Hook Form API: reset()

    React Hook Formのresetメソッドは、フォーム内の全てのフィールドの値をリセットし、フォーム内の全てのerrorsを消去します。


フォームの値を初期化するには?

React Hook Formは非制御コンポーネントによって出来ています。 非制御コンポーネントでは、それぞれのfieldに対してdefaultValuedefaultCheckedを指定出来ます。 実はこれよりも更に簡単な全てのインプット値の初期化方法をReact Hook Formは提供しています。 下記の例を参考して下さい。

import { useForm } from "react-hook-form";

export default function App() {
  const { register, handleSubmit } = useForm({
    defaultValues: {
      firstName: "bill",
      lastName: "luo",
      email: "bluebill1049@hotmail.com"
    }
  });
  const onSubmit = data => console.log(data);

  return (
    <form onSubmit={handleSubmit(onSubmit)}>
      <input {...register("firstName")} />
      <input {...register("lastName")} />
      <input {...register("email")} />

      <button type="submit">Submit</button>
    </form>
  );
}

refを共有するには?

React Hook Form では入力値を取得するためにrefが必要ですが、refを他の目的(ビューへのスクロールなど)に使用することもできます。下記の例を参考して下さい。

import React, { useRef } from "react";
import { useForm } from "react-hook-form";

export default function App() {
  const { register, handleSubmit } = useForm();
  const firstNameRef = useRef(null);
  const onSubmit = data => console.log(data);
  const { ref, ...rest } = register('firstName');

  return (
    <form onSubmit={handleSubmit(onSubmit)}>
      <input {...rest} name="firstName" ref={(e) => {
        ref(e)
        firstNameRef.current = e // you can still assign to ref
      }} />

      <button>Submit</button>
    </form>
  );
}import React, { useRef } from "react";
import { useForm } from "react-hook-form";

type Inputs = {
  firstName: string,
  lastName: string,
};

export default function App() {
  const { register, handleSubmit } = useForm<Inputs>();
  const firstNameRef = useRef<HTMLInputElement | null>(null);
  const onSubmit = data => console.log(data);
  const { ref, ...rest } = register('firstName');

  return (
    <form onSubmit={handleSubmit(onSubmit)}>
      <input {...rest} name="firstName" ref={(e) => {
        ref(e)
        firstNameRef.current = e // you can still assign to ref
      }} />

      <button>Submit</button>
    </form>
  );
}

refへのアクセスが出来ない場合は?

実はrefを使わずともregisterは使用出来ます。 加えてsetValuesetErrortriggerの手動での使用も出来ます。

注: ただしrefが登録されていないため, React Hook Formはinputのイベントリスナーへの登録が出来ず、 そのため値やエラーの更新を手動で行わなければいけません

import React, { useEffect } from "react";
import { useForm } from "react-hook-form";

export default function App() {
  const { register, handleSubmit, setValue, setError } = useForm();
  const onSubmit = data => console.log(data);

  useEffect(() => {
    register("firstName", { required: true });
    register("lastName");
  }, []);

  return (
    <form onSubmit={handleSubmit(onSubmit)}>
      <input
        name="firstName"
        onChange={e => setValue("firstName", e.target.value)}
      />
      <input
        name="lastName"
        onChange={e => {
          const value = e.target.value;
          if (value === "test") {
            setError("lastName", "notMatch")
          } else {
            setValue("lastName", e.target.value)
          }
        }}
      />
      <button>Submit</button>
    </form>
  );
}

ブラウザのサポートは?

React Hook Formは全ての主要なブラウザに対応しています。

IE11をサポートしたい場合は、IE11バージョンのreact-hook-formをインポートして下さい。

import { useForm } from 'react-hook-form/dist/index.ie11'; // V6
import { useForm } from 'react-hook-form/dist/react-hook-form.ie11'; // V5'
// Resolvers
import { yupResolver } from '@hookform/resolvers/dist/ie11/yup';

最初のキーストロークが機能しない場合は?

defaultValueの代わりにvalueを使っていないかよく確認して下さい。

React Hook Formは非制御インプットを基にして作られているため、インプットの値をonChangestateを通して変更する必要はありません。valueは使わずに、defaultValueでのインプットの初期値 の設定のみ行って下さい。


MutationObserverが原因でテストに失敗した場合は?

テスト中にMutationObserverが原因の問題が発生した場合は、mutationobserverをインストールしテストのsetup.jsでインポートしてください。


React Hook Form、FormikそれともRedux Form?

全てのライブラリはフォーム作成の体験を簡単で素晴らしいものにするという同じ問題を解決しようとしていますが 、3つのライブラリーの間にはいくつかの根本的な違いがあります。 react-hook-formは非制御入力を念頭に置いて開発されており、 ベストパフォーマンスのフォームを提供しようとし、再レンダリング数を出来る限り少なく抑えています。 さらに、react-hook-formはReact Hookによって構築され、hookとして使用されます。 つまり、コンポーネントをインポートしません。詳細な違いを以下に示します。

React Hook Form

Formik

Redux Form

Componentuncontrolledcontrolledcontrolled
Rendering最小限の再レンダリングローカル状態の変化に応じて再レンダリングします。つまり、入力時に変化します。状態管理ライブラリ(Redux)の変更に応じて再レンダリングします。 これは、入力時に変化することを意味します。
APIHooksComponent (RenderProps, Form, Field) + HooksComponent (RenderProps, Form, Field)
Package size
react-hook-form@3.26.2
5.3KB

formik@2.0.1
14.4KB

redux-form@8.2.6
27KB
ValidationBuilt-in & YupBuild yourself or YupBuild yourself or Plugins
学習曲線低い
状況小さなコミュニティ: 新しい成長中のライブラリ大きなコミュニティ: コミュニティによって十分に確立されたフォームライブラリ大きなコミュニティ: コミュニティによって十分に確立されたフォームライブラリ

制御されたコンポーネントと組み合わせて使用することができますか?

短い回答: Yes

React Hook Form は、制御されたフォームを構築することを推奨していませんが、 制御されたコンポーネントと組み合わせて簡単に構築することができます。

それは、watch API を使用して、各入力の変更を監視し、 value prop に割り当てるトリックです。

または、ラッパーコンポーネントの Controller を使用して、これらのカスタム登録を処理できます。

import { useForm, Controller } from "react-hook-form";

function App() {
  const { control } = useForm();
  
  return (
    <Controller
      render={({ field }) => <input {...field} />}
      name="firstName"
      control={control}
      defaultValue=""
    />
  );
}
import React, { useEffect } from "react";
import { useForm } from "react-hook-form";

function App() {
  const { register, watch, setValue, handleSubmit } = useForm({
    defaultValues: {
      firstName: "",
      lastName: ""
    }
  });
  const { firstName, lastName } = watch();

  useEffect(() => {
    register("firstName");
    register("lastName");
  }, [register]);

  const handleChange = (e, name) => {
    setValue(name, e.target.value);
  };

  const onSubmit = data => console.log(data);

  return (
    <form onSubmit={handleSubmit(onSubmit)}>
      <input
        onChange={(e) => handleChange(e, "firstName")}
        value={firstName}
      />

      <input onChange={(e) => handleChange(e, "lastName")} value={lastName} />
      <input type="submit" />
    </form>
  );
}

React Hook Form のテスト

  • act の警告が表示されるのはなぜですか?

    React Hook Form の全てのバリデーションメソッドは非同期関数として扱われるため、act async でラップすることが重要です。

  • fireEvent で入力の変更がトリガーされないのはなぜですか?

    React Hook Form は、入力の変更に input イベントを使用しています。 入力の変更がトリガーするために、 react-testing-library の fireEvent.input に簡単に切り替えることができます。

あなたのサポートが必要です

React プロジェクトで React Hook Form が役立つと思う場合は、リポジトリとコントリビューターをサポートするためにスターを付けてください ❤

Edit