Formik

Formikを試してみた

More than 1 year has passed since last update.

Reactでフォームを作るときにどうするのがいいのか調べてたらFormikがいいらしいので試してみる。

withFormik()で作る方法とFormikコンポーネントを直接使う方法がある。どちらも結果は同じなので好きな方を使えば良い、らしい。

withFormik()はHigher-Order Componentsというやつで取っつきにくいが記述が楽っぽいのでこちらでやる。


基本

最小のサンプル。

送信ボタンを押すと入力内容がコンソールに表示される。

import React from 'react'

import { withFormik } from 'formik'

const InnerForm = ({
handleChange,
handleSubmit
}) => (
<form onSubmit={handleSubmit}>
<input type="email" name="email" onChange={handleChange} />
<input type="submit" />
</form>
)

const SampleForm = withFormik({
handleSubmit: (values) => {
console.log(values)
}
})(InnerForm)

export default SampleForm

React DevToolsで見るとわかるがInnerFormコンポーネントがFormikにラップされる形になっている。

InnerFormhandleChangehandleSubmitのふたつのプロパティは必ずないといけない。

handleSubmitがないと送信ボタンを押した時に普通にページ遷移してしまう。

handleChangeがないとvaluesに入力値が入らない。


Fieldコンポーネント

<input>をそのまま使うとonChangeを入力項目ごとに都度書かないといけなかったりで面倒。

そのあたりを面倒みてくれるのがFieldコンポーネント。

こんなふうに書ける。

import React from 'react'

import { withFormik, Field } from 'formik'

const InnerForm = ({
handleSubmit
}) => (
<form onSubmit={handleSubmit}>
<Field type="email" name="email" />
<input type="submit" />
</form>
)

const SampleForm = withFormik({
handleSubmit: (values) => {
console.log(values)
}
})(InnerForm)

export default SampleForm

InnerFormhandleChangeプロパティが不要になった。

ただこれだとWarningが出る。

Warning: A component is changing an uncontrolled input of type email to be controlled.

ここ、よく分かっていないが、mapPropsToValuesを設定しておくといいらしい。

uncontrolled to controlled switch warning · Issue #28 · jaredpalmer/formik

const SampleForm = withFormik({

mapPropsToValues: props => ({
email: ''
}),
handleSubmit: (values) => {
console.log(values)
}
})(InnerForm)


Formコンポーネント

<form>onSubmitを書くのも定型的なので楽したい。

そういう時はFormコンポーネントを使う。

import React from 'react'

import { withFormik, Form, Field } from 'formik'

const InnerForm = () => (
<Form>
<Field type="email" name="email" />
<input type="submit" />
</Form>
)

const SampleForm = withFormik({
mapPropsToValues: props => ({
email: ''
}),
handleSubmit: (values) => {
console.log(values)
}
})(InnerForm)

export default SampleForm

InnerFormhandleSubmitプロパティが不要になった。

プロパティが何もなくなってとてもすっきり。


バリデーション

バリデーションについては今回試していないが、ドキュメントを読むかぎり他のパッケージと連携するようになっていて、Formik自身はあくまでフォームの実装に専念する形になっており、筋のよさを感じる。


まとめ

Formikのdescriptionに"without the tears"とあるがまさにそんな感じで、楽にフォームを実装できそうだった。