はじめに
仕事でコミュニティが活発なライブラリを活用することが増えてきたのですが、日本語の記事がなかったり、英語の記事を見ながら試行錯誤したので、備忘も兼ねてまとめます。
同じ悩みを抱える人の救いになれば幸いです。
(間違いがあればご指摘ください)
Formik
Formik とは、Reactで使えるフォームの管理をしてくれるイケてるライブラリです。
同僚が使う理由として
"its the lib recommended by the formskit team"
を挙げていました。
ごめんなさい、ドヤ顔で言われてもそのすごさを理解できてないヘボヘボエンジニアです。
というか、Ant Design の Form Component であらかた入力フォームとバリデーション実装したタイミングだったので、「マジかよ…」と思いました。
yup
yup は、Yup is a JavaScript object schema validator and object parser.
とあるように、 formik と連携してバリデーションチェックをしてくれるイケてるやつです。
formik のvalidationSchema
に yup のオブジェクトスキーマをセットしておけば、handleSubmitの際にチェックして、エラーだと onSubmit が呼び出されません。
余談ですが、yup のバリデーションを通過しているのに formik のprops.isValid
の値が false になってることがありました。
yup はasync validation
と書かれてるので、この辺りが原因?かもしれません。
props.isValid
で判断することはやめて、真っ当にonSubmit
に処理を書いてあげれば問題ないかと思います。
yup のバリデーション設定
本題に入ります。
他の項目とチェックしたいケースで一番用途が大きいのが確認用パスワードだと思います。
これはoneOf
を利用すれば簡単に実装可能です。
import * as yup from 'yup';
/*** 中略 ***/
const validationSchema = yup.object().shape({
password: yup.string()
.required(),
passwordConfirmation: yup.string()
.oneOf([yup.ref('password')])
.required(),
});
次に、もうちょっとダイナミックに他の項目を使う方法ですが、下記の方法で実装可能です。
import * as yup from 'yup';
/*** 中略 ***/
const validationSchema = yup.object().shape({
optionalValue: yup.string()
.required(),
optionalDetail: yup.string()
.test('optionalDetail', 'otherValidation', function(value) {
if (this.parent.optionalValue === 'other' && value === undefined) {
return false;
}
return true;
}),
});
test
のコールバック関数としてarrow function
を使うとthis
が束縛されてしまうので、function()
の形で記載します。
おわりに
初めての Qiita 投稿が少しニッチな内容になりました。
もっといい方法あるんじゃないか、あればぜひご紹介いただけると幸いです。