Skip to content

React Hook Form

高性能で柔軟かつ拡張可能な使いやすいフォームバリデーションライブラリ。

React Web

React Native

Happy
Birthday

06/03/2019

1st

🏅Achievements

  • ★ OS Awards: nominated as
    Breakthrough of the year

  • ★ NPM downloads: 1.5M

  • ★ Github stars: 7.5K

  • ★ Github commit: 1.6K

  • ★ Github issues resolved 600+

🎁 Send ★ Gift

特徴

</>

DX

直感的で完全な機能の API はフォームを構築する際に開発者に優れたエクスペリエンスの提供します。

HTML 標準

HTML 標準

既存の HTML マークアップを活用し、Constraint Validation API でフォームバリデーションを開始します。

超軽量

超軽量

パッケージのサイズもパフォーマンス同様に重要です。依存関係のない小さなライブラリです。

パフォーマンス

パフォーマンス

再レンダリング数を最小限に抑えマウントを高速化し、最高なユーザーエクスペリエンスを提供します。

適応性

適応性

フォームの状態は、ローカルで管理されるため、他に依存せず簡単に使用することができます。

ライブラリのコード比較

コードの記述量を減らすことは、React Hook Form の主な目標の一つです。 これを説明するために、最も一般的なフォームバリデーションライブラリを使用した非常にシンプルなコードを見てみましょう。

⚠ 注意:下記の Formik と Redux-Form のコードは公式ドキュメントからコピーされています。

Formik

import React from "react";
import { Formik, Form, Field } from "formik";

function validateEmail(value) {
  let error;
  
  if (!value) {
    error = "Required";
  } else if (!/^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}$/i.test(value)) {
    error = "Invalid email address";
  }
  
  return error;
}

function validateUsername(value) {
  let error;
  
  if (value === "admin") {
    error = "Nice try!";
  }
  
  return error;
}

const Example = () => {
  const onSubmit = values => {
    console.log(values);
  };

  return (
    <Formik
      initialValues={{
        username: "",
        email: ""
      }}
      onSubmit={onSubmit}
    >
      {({ errors, touched }) => (
        <Form>
          <Field name="email" validate={validateEmail} />
          {errors.email && touched.email && errors.email}

          <Field name="username" validate={validateUsername} />
          {errors.username && touched.username && errors.username}

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

React Hook Form

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

const Example = () => {
  const { handleSubmit, register, errors } = useForm();
  const onSubmit = values => {
    console.log(values);
  };

  return (
    <form onSubmit={handleSubmit(onSubmit)}>
      <input
        name="email"
        ref={register({
          required: 'Required',
          pattern: {
            value: /^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}$/i,
            message: "invalid email address"
          }
        })}
      />
      {errors.email && errors.email.message}

      <input
        name="username"
        ref={register({
          validate: value => value !== "admin" || "Nice try!"
        })}
      />
      {errors.username && errors.username.message}

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

Redux Form

import React from "react";
import { Provider } from "react-redux";
import { Field, reduxForm } from "redux-form";
import store from "./store";

const validate = values => {
  const errors = {};

  if (!values.username) {
    errors.username = "Required";
  } else if (values.username === "admin") {
    errors.username = "Nice try!";
  }

  if (!/^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}$/i.test(values.email)) {
    errors.email = "Invalid email address";
  }

  return errors;
};

const renderField = ({ input, label, type, meta: { touched, error } }) => (
  <>
    <input {...input} placeholder={label} type={type} />
    {touched && error && <span>{error}</span>}
  </>
);

const Form = props => {
  const { handleSubmit } = props;
  const onSubmit = values => {
    console.log(values);
  };

  return (
    <form onSubmit={handleSubmit(onSubmit)}>
      <Field name="email" type="email" component={renderField} label="Email" />
      <Field name="username" component={renderField} label="Username" />
    
      <button type="submit">Submit</button>
    </form>
  );
};

const FormRedux = reduxForm({ form: "syncValidation", validate })(Form);

const Example = () => (
  <Provider store={store}>
    <FormRedux />
  </Provider>
);

コンポーネントの再レンダリングを分離

コンポーネントの再レンダリングを分離して、ページまたはアプリケーションのパフォーマンスを向上させることができます。 次の例は、このような動作を示しています。

注意: 入力欄に入力してレンダリングの動作を確認してください。

React Hook Form

Child Component A
Child Component B
Child Component C

VS

Controlled Form

Child Component A
Child Component B
Child Component C

レンダリングを削減

ユーザーによってどのくらいコンポーネントが再レンダリングされたか気になったことはありますか? React Hook Form は非制御フォームバリデーションを採用してパフォーマンスへの影響を軽減します。

合計再レンダリング数: 30+

合計再レンダリング数: 3

合計再レンダリング数: 30+

高速なマウント

下記の結果は、コンポーネントのレンダリングにかかった時間を示しています。 Chrome DevTools の Performance タブを使用して、 CPU のパフォーマンスを6倍低速化させた環境での測定結果です。 実行コードは上記のライブラリのコード比較セクションのものです。

React Hook Form

  • マウント数: 1
  • 変更コミット数: 1
  • 合計時間: 1800ms
React Hook Form performance

Formik

  • マウント数: 6
  • 変更コミット数: 1
  • 合計時間: 2070ms
Formik performance

Redux Form

  • マウント数: 17
  • 変更コミット数: 2
  • 合計時間: 2380ms
Redux Form performance

より強力なパフォーマンステストを見たいですか?こちらから1000フィールドを含むフォームのパフォーマンテスト結果をご覧ください

ライブデモ

下記のフォームは、実行中のフォームバリデーションを示しています。 各列はカスタムフックに取り込まれた内容を表します。編集ボタンをクリックしてフォームのフィールドを変更することもできます。

or

監視

監視されている値を表示するには入力値を変更します。

{}

エラー

ここにバリデーションエラーが表示されます。

タッチ

タッチされたフィールドがここに表示されます。

[]

便利で面白いと思いますか?

フォームバリデーションはより簡単にする必要があります。React Hook Form を使用すると、コードの記述が少なくなり、パフォーマンスが向上します。はじめるセクションを見て、API ドキュメントページで詳細を確認してください。