formik vs formik-material-ui vs react-final-form vs react-hook-form vs react-jsonschema-form vs redux-form
Reactフォーム管理ライブラリの技術的比較
formikformik-material-uireact-final-formreact-hook-formreact-jsonschema-formredux-form類似パッケージ:

Reactフォーム管理ライブラリの技術的比較

formikformik-material-uireact-final-formreact-hook-formreact-jsonschema-formredux-form はすべて React アプリケーションにおけるフォーム状態管理、バリデーション、送信処理を支援するライブラリです。これらのライブラリは、フォームの複雑さや開発者の好みに応じて異なるアプローチを取ります。formikreact-final-form はコンポーネントベースの制御を重視し、react-hook-form は uncontrolled コンポーネントと React Hooks を活用してパフォーマンスを最適化します。formik-material-uiformik の上に Material UI との統合レイヤーを提供します。react-jsonschema-form は JSON Schema からフォームを自動生成するユースケースに特化しています。一方、redux-form は Redux ストアにフォーム状態を保存する古くからのアプローチを採用していますが、現在は非推奨となっています。

npmのダウンロードトレンド

3 年

GitHub Starsランキング

統計詳細

パッケージ
ダウンロード数
Stars
サイズ
Issues
公開日時
ライセンス
formik034,385585 kB8364ヶ月前Apache-2.0
formik-material-ui0979-314年前MIT
react-final-form07,440215 kB3749ヶ月前MIT
react-hook-form044,5621.25 MB12215日前MIT
react-jsonschema-form015,670-1916年前Apache-2.0
redux-form012,5161.45 MB4973年前MIT

Reactフォーム管理ライブラリ:Formik、React Hook Form、Final Form、JSON Schema Form、Redux Formを徹底比較

Reactアプリケーションでフォームを扱う際、状態管理、バリデーション、送信処理、エラーハンドリングなど多くの面倒事を自分で実装するのは非効率です。そのため、専用のフォーム管理ライブラリが広く使われています。ここでは、代表的な6つのパッケージ — formikformik-material-uireact-final-formreact-hook-formreact-jsonschema-formredux-form — を技術的観点から比較します。

重要: redux-form は npm ページおよび GitHub リポジトリで公式に非推奨(deprecated)とされています。新規プロジェクトでは使用しないでください。

📝 基本的なフォーム実装:各ライブラリの書き方

まずは、メールアドレスとパスワードを入力するシンプルなログインフォームを、各ライブラリでどう実装するかを見てみましょう。

formik

formik は controlled コンポーネント方式で、内部状態を管理します。useFormik フックまたは <Formik> コンポーネントでフォームをラップします。

import { useFormik } from 'formik';
import * as yup from 'yup';

const validationSchema = yup.object({
  email: yup.string().email().required(),
  password: yup.string().min(8).required()
});

function LoginForm() {
  const formik = useFormik({
    initialValues: { email: '', password: '' },
    validationSchema,
    onSubmit: (values) => console.log(values)
  });

  return (
    <form onSubmit={formik.handleSubmit}>
      <input
        name="email"
        value={formik.values.email}
        onChange={formik.handleChange}
        onBlur={formik.handleBlur}
      />
      {formik.touched.email && formik.errors.email ? <div>{formik.errors.email}</div> : null}

      <input
        name="password"
        type="password"
        value={formik.values.password}
        onChange={formik.handleChange}
        onBlur={formik.handleBlur}
      />
      {formik.touched.password && formik.errors.password ? <div>{formik.errors.password}</div> : null}

      <button type="submit">ログイン</button>
    </form>
  );
}

formik-material-ui

これは formik と Material UI の橋渡しをするだけのライブラリです。formik のロジックはそのまま、UI コンポーネントだけを置き換えます。

import { useFormik } from 'formik';
import { TextField, Button } from '@mui/material';
import { TextField as FormikTextField } from 'formik-material-ui';

function LoginForm() {
  const formik = useFormik({
    initialValues: { email: '', password: '' },
    onSubmit: (values) => console.log(values)
  });

  return (
    <form onSubmit={formik.handleSubmit}>
      <FormikTextField name="email" label="メールアドレス" fullWidth />
      <FormikTextField name="password" label="パスワード" type="password" fullWidth />
      <Button type="submit">ログイン</Button>
    </form>
  );
}

react-final-form

react-final-form は render props パターンを使い、フィールドごとの再レンダリングを最適化します。

import { Form, Field } from 'react-final-form';
import { required, email, minLength } from 'react-final-form-validators';

const validate = (values) => {
  const errors = {};
  if (!values.email) errors.email = '必須です';
  else if (!/^[^@]+@[^@]+$/.test(values.email)) errors.email = 'メール形式で入力してください';
  if (!values.password) errors.password = '必須です';
  else if (values.password.length < 8) errors.password = '8文字以上にしてください';
  return errors;
};

function LoginForm() {
  return (
    <Form
      onSubmit={(values) => console.log(values)}
      validate={validate}
      render={({ handleSubmit, pristine, invalid }) => (
        <form onSubmit={handleSubmit}>
          <Field name="email">
            {({ input, meta }) => (
              <div>
                <input {...input} placeholder="メールアドレス" />
                {meta.error && meta.touched && <span>{meta.error}</span>}
              </div>
            )}
          </Field>

          <Field name="password">
            {({ input, meta }) => (
              <div>
                <input {...input} type="password" placeholder="パスワード" />
                {meta.error && meta.touched && <span>{meta.error}</span>}
              </div>
            )}
          </Field>

          <button type="submit" disabled={pristine || invalid}>ログイン</button>
        </form>
      )}
    />
  );
}

react-hook-form

react-hook-form は uncontrolled コンポーネントを基本とし、register でフィールドを登録します。バリデーションはスキーマまたはビルトインルールで定義可能です。

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

function LoginForm() {
  const { register, handleSubmit, formState: { errors } } = useForm({
    defaultValues: { email: '', password: '' }
  });

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

  return (
    <form onSubmit={handleSubmit(onSubmit)}>
      <input
        {...register('email', {
          required: '必須です',
          pattern: { value: /^[^@]+@[^@]+$/, message: 'メール形式で入力してください' }
        })}
        placeholder="メールアドレス"
      />
      {errors.email && <span>{errors.email.message}</span>}

      <input
        {...register('password', {
          required: '必須です',
          minLength: { value: 8, message: '8文字以上にしてください' }
        })}
        type="password"
        placeholder="パスワード"
      />
      {errors.password && <span>{errors.password.message}</span>}

      <button type="submit">ログイン</button>
    </form>
  );
}

react-jsonschema-form

このライブラリは JSON Schema からフォームを自動生成します。UI スキーマで見た目を調整可能です。

import Form from 'react-jsonschema-form';

const schema = {
  type: 'object',
  properties: {
    email: { type: 'string', format: 'email', title: 'メールアドレス' },
    password: { type: 'string', minLength: 8, title: 'パスワード' }
  },
  required: ['email', 'password']
};

const uiSchema = {
  password: { 'ui:widget': 'password' }
};

function LoginForm() {
  const onSubmit = ({ formData }) => console.log(formData);

  return (
    <Form
      schema={schema}
      uiSchema={uiSchema}
      onSubmit={onSubmit}
    />
  );
}

redux-form(非推奨)

redux-form は Redux ストアにフォーム状態を保存します。新規プロジェクトでは使用しないでください。

// 非推奨のため、参考までに記載
import { reduxForm, Field } from 'redux-form';

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

let LoginForm = (props) => {
  const { handleSubmit } = props;
  return (
    <form onSubmit={handleSubmit((values) => console.log(values))}>
      <Field name="email" component={renderField} label="メールアドレス" />
      <Field name="password" component={renderField} label="パスワード" type="password" />
      <button type="submit">ログイン</button>
    </form>
  );
};

LoginForm = reduxForm({ form: 'login' })(LoginForm);

⚡ パフォーマンスと再レンダリング戦略

formik

formik はフォーム全体の状態を1つのオブジェクトで管理するため、1つのフィールドを更新してもフォーム全体が再レンダリングされる可能性があります。useMemoReact.memo で子コンポーネントを最適化する必要があります。

react-final-form

フィールド単位で状態を分離し、変更があったフィールドだけを再レンダリングする仕組みを備えています。これにより、大規模フォームでも高いパフォーマンスを維持できます。

react-hook-form

uncontrolled コンポーネントを採用しているため、React の状態管理を介さず、DOM から直接値を取得します。これにより、不要な再レンダリングが発生せず、パフォーマンスが非常に優れています。

react-jsonschema-form

フォーム全体を1つのコンポーネントとして扱うため、フィールドの変更時に全体が再レンダリングされます。複雑なフォームではパフォーマンスのボトルネックになる可能性があります。

redux-form

Redux ストアに状態を保存するため、フィールド変更のたびにアクションがディスパッチされ、ストアが更新されます。大規模アプリではパフォーマンスに悪影響を及ぼすため、非推奨となっています。

🔧 バリデーションの柔軟性

  • formik: Yup や他のバリデーションライブラリと連携可能。非同期バリデーションもサポート。
  • react-final-form: 同期・非同期バリデーションをカスタム関数で自由に実装可能。
  • react-hook-form: ビルトインルール、Yup、Zod、Joi など多彩なバリデーションスキーマに対応。非同期バリデーションも可能。
  • react-jsonschema-form: JSON Schema の標準バリデーションルールに依存。カスタムバリデーションは可能だがやや制限あり。
  • redux-form: カスタムバリデーション関数をサポートしていたが、非推奨のため新規開発では考慮不要。

🧩 複雑なフォームへの対応(動的フィールド、ネストなど)

  • formik: useFieldFieldArray を使って動的リストやネストされたオブジェクトを簡単に扱えます。
  • react-final-form: FieldArray 相当の機能はコミュニティプラグインが必要。ネイティブサポートは弱め。
  • react-hook-form: useFieldArray フックで動的フィールドを強力にサポート。ネストも問題なし。
  • react-jsonschema-form: JSON Schema の arrayobject 型で表現可能ですが、UI カスタマイズが難しい場合があります。

🎨 UI フレームワークとの統合

  • formik-material-uiformik 専用の Material UI 統合レイヤーです。他の UI ライブラリ(例: Ant Design、Chakra UI)を使う場合は、それぞれのコミュニティ製統合パッケージを探す必要があります。
  • react-hook-form は uncontrolled 方式のため、どの UI ライブラリとも簡単に統合できます。
  • react-final-form も render props の柔軟性により、任意の UI コンポーネントと接続可能です。

📌 まとめ:どのライブラリを選ぶべきか?

ライブラリ推奨されるユースケース注意点
formik中規模フォーム、Yup との連携、動的フィールドが必要大規模フォームでは再レンダリングに注意
formik-material-uiformik + Material UI を使うプロジェクトMaterial UI 以外では不要
react-final-form高パフォーマンスが求められる大規模フォームrender props の記述が冗長になりがち
react-hook-formパフォーマンス重視、シンプルなAPI、TypeScript対応uncontrolled 方式に慣れる必要あり
react-jsonschema-formJSON Schema からフォームを自動生成する必要がある場合複雑なカスタムロジックには不向き
redux-form非推奨 — 新規プロジェクトでは使用禁止レガシー保守のみ

💡 最終的なアドバイス

  • 新規プロジェクトでは、まず react-hook-form を検討してください。パフォーマンス、シンプルさ、TypeScript サポートのバランスが非常に優れています。
  • Material UI を使い、formik に慣れているチームなら、formik-material-ui で開発速度を上げられます。
  • JSON Schema に基づく動的フォームが必要なら、react-jsonschema-form が唯一の選択肢です。
  • redux-form は絶対に使わないでください。公式に非推奨であり、現代の React 最適化手法と相性が悪いです。

フォームはユーザー体験の要です。適切なライブラリを選ぶことで、開発効率とアプリケーションの品質を同時に高めることができます。

選び方: formik vs formik-material-ui vs react-final-form vs react-hook-form vs react-jsonschema-form vs redux-form

  • formik:

    formik は中規模以上のフォームで、バリデーションやフィールド間の依存関係が複雑な場合に適しています。Context API とカスタムフックを組み合わせた柔軟な設計により、ネストされたフィールドや動的フィールドの追加・削除も容易に実装できます。ただし、大規模なフォームでは再レンダリングのオーバーヘッドが発生する可能性があるため、パフォーマンス要件が高い場合は注意が必要です。

  • formik-material-ui:

    formik-material-ui は既に formik を採用しており、UI フレームワークとして Material UI を使用しているプロジェクトに最適です。このライブラリは formikField コンポーネントと Material UI の入力コンポーネント(例: TextField)を簡単に接続するためのヘルパーを提供します。ただし、Material UI 以外の UI ライブラリを使用している場合は不要です。

  • react-final-form:

    react-final-form は高性能かつ軽量なフォーム管理を必要とするプロジェクトに適しています。render props パターンを採用しており、再レンダリングを最小限に抑える仕組み(フィールド単位の更新通知)を備えています。ただし、render props の記述スタイルは JSX の可読性を下げる可能性があり、Hooks ベースのコードを好むチームには向かないかもしれません。

  • react-hook-form:

    react-hook-form はパフォーマンスとシンプルさを重視するプロジェクトに最適です。uncontrolled コンポーネントを基本とし、登録されたフィールドのみを監視することで、不要な再レンダリングを回避します。TypeScript との相性も非常に良く、バリデーションルールも直感的に記述できます。ただし、完全に uncontrolled な設計のため、動的フィールドの制御や高度なカスタムロジックには若干の学習コストがあります。

  • react-jsonschema-form:

    react-jsonschema-form は JSON Schema に基づいてフォームを動的に生成する必要がある場合(例: 設定画面、CMS、API ドキュメントからのフォーム生成)に最適です。UI スキーマを使って見た目をカスタマイズ可能ですが、複雑なインタラクションやカスタムバリデーションロジックが必要な場合は柔軟性に欠けることがあります。一般的な静的フォームにはオーバーエンジニアリングになる可能性があります。

  • redux-form:

    redux-form は公式に非推奨(deprecated)とされており、新規プロジェクトでの使用は避けるべきです。過去に Redux を深く活用していたレガシープロジェクトの保守にはまだ使われることがありますが、新しい開発では formikreact-hook-form などの現代的な代替手段を検討してください。Redux ストアにフォーム状態を保存するアプローチは、不要な状態の肥大化とパフォーマンス劣化を引き起こすことが多いため、現在のベストプラクティスとは見なされていません。

formik のREADME

Formik.js

Build forms in React, without the tears.


Stable Release Blazing Fast gzip size license Discord

Visit https://formik.org to get started with Formik.

Organizations and projects using Formik

List of organizations and projects using Formik

Authors

Contributing

This monorepo uses yarn, so to start you'll need the package manager installed.

To run E2E tests you'll also need Playwright set up, which can be done locally via npx playwright install. Afterward, run yarn start:app and in a separate tab run yarn e2e:ui to boot up the test runner.

When you're done with your changes, we use changesets to manage release notes. Run yarn changeset to autogenerate notes to be appended to your pull request.

Thank you!

Contributors

Formik is made with <3 thanks to these wonderful people (emoji key):


Jared Palmer

💬 💻 🎨 📖 💡 🤔 👀 ⚠️

Ian White

💬 🐛 💻 📖 🤔 👀

Andrej Badin

💬 🐛 📖

Adam Howard

💬 🐛 🤔 👀

Vlad Shcherbin

💬 🐛 🤔

Brikou CARRE

🐛 📖

Sam Kvale

🐛 💻 ⚠️

Jon Tansey

🐛 💻

Tyler Martinez

🐛 📖

Tobias Lohse

🐛 💻

This project follows the all-contributors specification. Contributions of any kind welcome!

Related

  • TSDX - Zero-config CLI for TypeScript used by this repo. (Formik's Rollup configuration as a CLI)

Apache 2.0 License.