3
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Formikの基本的な使い方と、MaterialUIでの使用例

Last updated at Posted at 2021-07-29

以前の案件で使ったFormikのメモです。
公式ドキュメントがやはり一番詳しいですが、
初めて使う人は簡単な概要があったほういいかもしれないので、記事にしておきます。

Formikとは?

FormikはReactのフォームの扱いをシンプルにしてくれるライブラリです。

[Formik公式ドキュメント] (https://formik.org/docs/overview)
おそらく世界で一番使われているReactのフォームライブラリじゃないかなと思います。
npm trendsで他ライブラリと比較してみました。

スクリーンショット 2021-07-30 0.02.00.png

react-hook-formも伸びてきていますが、他ライブラリとかなり差が開いていますね。

Formikは以下3点を受け持ってくれます。

  • formの状態管理
  • バリデーション
  • フォームのsubmit処理

フォームの状態管理にはRedux-Formというライブラリもありますが、
Formikの方がシンプルっぽいです。
Redux使うと、複雑になりやすいので、
Formikの方がいいケースの方が多いんじゃないかなと思います。

バリデーションについては、Yupというライブラリとセットで使うことが多いです。公式でもYupいいよね的なこと言ってますね。

Formikの使い方概要

とりあえずインストールしましょう。

npm install formik --save
// または
yarn add formik

使い方は大きく分けて3種類あります。

  • useFormikを使って書くやり方
  • withForimikを使う書き方
  • JSXのreturn部分で<Formik>コンポーネントを使って書いていくやり方

Formikコンポーネントを使って書いた方が簡潔にかけます。
一方、materialUIなどのコンポーネントで使う場合にはuseFormikを使うというやり方があります。

この記事ではuseFormikを使った記述内容中心にして、
別記事でFormikコンポーネントを使った方法を書いて行こうかなと思います。

ちなみにFormikコンポーネントはuseFormikを内部的に使っています。

useFormikの使い方ざっくり

大体以下の感じになるかと思います。

  • useFormikを使い、引数や型でフォームの情報を設定。
    • フォームで何を扱うかを型で設定
    • 初期値の設定
    • バリデーションの設定
    • formのonSubmit時の処理の設定
  • formタグのonSubmitプロパティにformik.handleSubmitを設定
  • 各フォーム要素にformikのバリューやイベントを設定

コードで書いてみると以下のような感じのサンプルに鳴ります。

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

const SampleComponent = () => {

  const formik = useFormik<Type>({
    // フォームに初期値を設定
    initialValues: {
      email: '',
      password: '',
    },
    // バリデーション
    validationSchema: validationSchema,
    // submit時のファンクション
    onSubmit: values => {
      // valuesはformの現在の値を返す。
      alert(JSON.stringify(values, null, 2))
    },
  });

  return (
    <form onSubmit={formik.handleSubmit}>
      <label htmlFor="email">Email Address</label>
      <input
        // idとnameをinitialValuesで設定したプロパティと合わせて設定
        id="email"
        name="email"
        type="email"
        onChange={formik.handleChange}
        onBlur={formik?.handleBlur}
        value={formik.values.email}
      >
      <label htmlFor="password">Password</label>
      {formik.errors.email ? <div>{formik.errors.email}</div> : null}

      <input
        id="password"
        name="password"
        type="password"
        onChange={formik.handleChange}
        onBlur={formik?.handleBlur}
        value={formik.values.password}
      >
      {formik.errors.password ? <div>{formik.errors.password}</div> : null}
      <button type="submit">Submit</button>
    </form>
  )
}

const SignupSchema = Yup.object().shape({
   email: Yup.string().email()
     .required('Required'),
   password: Yup.string()
     .min(2, 'Too Short!')
     .max(50, 'Too Long!')
     .required('Required'),
   email: Yup.string().email('Invalid email').required('Required'),
});

inputの設定プロパティが少し多い感じがしますね。
タグを使うやり方であれば、もっとシンプルに書けます。

よく使いそうなプロパティ

他にも色々とありますが、以下の3つはよく使いました。

// 特定のフォーム要素に値を設定。
formik.setFieldValue('email', 'aaa@example.com')
// 複数のフォーム要素に値を設定。APIで取得した値を一括で設定したいときなどに利用
formik.setValues(values)
// フォームの値をリセット
formik.handleReset

MaterialUIでの使い方

TextFieldやRadioButtonはアプリケーションの中でよくある要素なので、
コンポーネント分割されて使いまわされるケースが多いと思います。
そんな場合位はこんな感じにformikをpropsで渡してあげればいいです。

interface Props {
	name: string;
  formik?: ReturnType<typeof useFormik>;
}

const TextFieldParts: FC<Props> = ({name, formik}) => {
  return <TextField
    ~~
    value={formik?.values[name]}
    onChange={formik?.handleChange}
    onBlur={formik?.handleBlur}
    error={Boolean(formik?.errors[name])}
    helperText={formik?.errors[name]}
    ~~
  />
};
3
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?