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にラップされる形になっている。
InnerFormのhandleChangeとhandleSubmitのふたつのプロパティは必ずないといけない。
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
InnerFormのhandleChangeプロパティが不要になった。
ただこれだと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
InnerForm のhandleSubmitプロパティが不要になった。
プロパティが何もなくなってとてもすっきり。
バリデーション
バリデーションについては今回試していないが、ドキュメントを読むかぎり他のパッケージと連携するようになっていて、Formik自身はあくまでフォームの実装に専念する形になっており、筋のよさを感じる。
まとめ
Formikのdescriptionに"without the tears"とあるがまさにそんな感じで、楽にフォームを実装できそうだった。