仕事で使えるようになるまで Formik を理解するためにドキュメントをしっかり読んでみた

## はじめに

今までなんとなく使用していたので、英語のドキュメントを読んで仕事に応用するまでの記録してみます。

## Formikとは

Formikとは、Reactでよく使われているツールで、フォームで使う機能を簡単かつ簡潔に実装できるようにしてくれるライブラリーです。要は、フォーム管理ツールです。

ドキュメントは👇

https://formik.org/docs/overview

読んでいきます。

## 学びや気づき

Formik を理解する上で大事な要素を学びます。

### `<Field />`（Fieldコンポーネント）

`<Field />` は name属性を使用して自動的に Formik に入力を伝えます。デフォルトは HTML の `<input />` 要素になります。

なぜ `<Field />` を使うのか？

どの要素にも必ず必要な`handleChange`をすべての要素でpropsとして渡すのは、無駄ですよね？
そんなとき、FormikのFieldコンポーネントを使うと、`handleChange`や`error`をpropsとして送る必要がなくなります。
便利なやつです。

https://formik.org/docs/api/field

#### name 属性

Fieldの一意の識別子です。

`id` や `name` を使って識別する。

例えば、`formik.values.email` でアクセスできます。

```jsx
<input
  id="email"
  name="email"
  type="email"
  onChange={formik.handleChange}
  value={formik.values.email}
/>
```

### `<Form />`（Formコンポーネント）

`<Form />`（Formコンポーネント）はHTML の<form> 要素の小さなラッパーです。

Formik の handleSubmit と handleReset に自動的にフックします。他のすべてのプロップは DOM ノードに直接渡されます。

### `<FieldArray />`（FieldArray コンポーネント）

一般的な配列/リストの操作を支援するコンポーネントです。

これに、関連する配列を保持する値の中のキーへのパスを持つ name プロパティを渡します。

### 実際の使われ方

```jsx

const InnerForm = (form) => {
  return ( < Component/> )
}

const RequestForm = withFormik({
  mapPropsToValues: ({ props }) => ({ initialValues}),
  validationSchema: Yup.object().shape({バリデーションの設定}),
  mapPropsToStatus: () => ({ triedSubmit: false }),
  validateOnMount: true,
  handleSubmit: (values, { props: { handleSubmit }, ...actions }) => {
    handleSubmit(values, actions)
  },
})(InnerForm)
```


![IMG_BF65009D4F6F-1.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/14191/491d8a40-5607-4800-beb9-00c3736e8c9f.jpeg)


DevToolで見るとわかるが、`InnerForm`コンポーネントが`Formik`にラップされています。

#### withFormik とは

`withFormik()`で作る方法と`Formik`コンポーネントを直接使う方法があるみたい。

withFormik のOptionに
- mapPropsToValues
- validationSchema
- mapPropsToStatus
- validateOnMount
- handleSubmit

など、があります。

#### mapPropsToValues とは

このオプションが指定された場合、Formik は状態変化を更新可能なフォームに転送し、これらの値を props.values として新しいコンポーネントで利用できるようにします。

`withFormik()`でinitialValuesを設定する際に使われます。

詳しい具体例は、以下の[記事](https://qiita.com/okonomi/items/6aee9c4cfa9eeed6d8ea#field%E3%82%B3%E3%83%B3%E3%83%9D%E3%83%BC%E3%83%8D%E3%83%B3%E3%83%88)をみて欲しいです。

```
Warning: A component is changing an uncontrolled input of type email to be controlled.
警告。コンポーネントが、制御されていないemail型の入力を制御対象に変更しています。
```

というエラーが出るための対策として、mapPropsToValuesを使っています。

https://formik.org/docs/api/withFormik#mappropstovalues-props-props--values

#### validationSchema とは

Formikが持つYup用の特別な設定オプション

#### mapPropsToStatus とは

更新可能なフォームの状態に転送し、これらの値を `props.status` として新しいコンポーネントで利用できるようにします。任意の状態をフォームに保存したり、インスタンス化したりするのに便利です。

#### validateOnMount とは

このオプションを使用して、コンポーネントがマウント（レンダリングされることをマウントという）またはinitialValues変更されたときに検証を実行するようにFormikに指示します。

デフォルトはfalseです。

#### handleSubmit とは

サブミットの処理をするやつです。データ送信のハンドラです。

## formik.errors

custom validation function を介して入力されます。

キースストロークごとに、全てのエラーオブジェクトに格納される。

### touched

Formik はどのフィールドがタッチされたかを追跡することができる。
この情報は `touched` と呼ばれるオブジェクトに保存されます。
各キーは boolean true/false のみです。

touched を利用するために、`formik.handleBlur` を各入力の `onBlur` プロップに渡すことができます。この関数は`formik.handleChange`と似たように動作します。

どのフィールドを更新するかを決定するためにname属性を使用します。

### handleChange

1ページにおける全ての form要素（例えば`<input>`, `<select>`, `<textarea>`）に対して、handleChangeは、一括で再利用される。

### values

フォームが持つ要素の現在の値

### `<ErrorMessage />`

### バリデーション（検証）に関して

Formikにおいて、バリデーション（検証）は使い手（開発者）、つまりあなたに任されています。

カスタム検証関数`validate`関数の代わりに、

#### yup

検証には、Yupというライブラリがよく用いられています。

Formikには`validationSchema`と呼ばれるYupのための特別な設定オプションがあります。

#### validationSchema

Formikが持つYup用の特別な設定オプション

## 参考

- [Formikを試してみた \- Qiita](https://qiita.com/okonomi/items/6aee9c4cfa9eeed6d8ea)
- [Better React Forms with Formik \- YouTube](https://www.youtube.com/watch?v=yNiJkjEwmpw&t=445s)
- [FormikでReactのformを簡単に扱おう！ \- Qiita](https://qiita.com/ryubb_SU/items/b430eb77f779257c2a48)