Reactでフォームを作成する際に「handleChange」、「handleSubmit」はよく目にし、だいたいどんなものかご理解されている方は多いと思います
ただFormikを使っていると必ず出てくるのが
handleBlur
これは一体なんでしょうか?
わからないで使うのは気持ちが悪い、
詳しく知れば何か応用につながる、
などとお考えの方は是非ご一読頂き参考になれば幸いです!
handleBlurの役割
結論を先にお伝えします
handleBlurがあることで、
フォーカスが外れるまでエラー判定を待ってくれます
※フォーカスとは入力フォームを選択肢し、入力できる状態になっていること。
言葉ではわかりにくいかもしれませんのでHTMLページの画像で見てみましょう
handleBlur無し
文字を1文字でも打つと
エラー表示されます!
名前を打っているのにも関わらず、メールアドレスフォームのエラーが既に発動します
ちょっと不便ですよね?
handleBlurを設定
文字を打っても先程のエラーは出てきません!
設定のためのコード
handleBlurを設定するために、下記を追記してます
<input
....
....
onBlur={formik.handleBlur}
....
/>
{ formik.touched.name &&formik.errors.....}
何がおきてるの?
formik.touched.<フォームname>
とは、そのフォームが一度でもフォーカスされて外れる、つまり入力が終わったと判断された時に「true」に変わる属性です
この属性をチェックしエラーを出し入れしているのが、handleBlurです
つまり、formik.touchedが設定されていても、formik.handleBlurが設定されていなければ効果はありません
まとめ
私は当初、
handleBlurって何?
handleBlurっているの?
なんて浅はかに思っていました
ただ学んでいくと、
formik.touchedの値により、エラーを出し入れする
役割があることを知り、不可欠であることを認識した次第です
この知識が直接役に立つかはわかりませんが、少しでも皆様のなんで?どうして?にお答えできていれば嬉しいです!
最後にはなりますが、今回のコードを下記の通り参考までお見せします
最後までご覧いただき、ありがとうございました!!!
【今回のコード】
cssではbootstrapを使っています
import React from "react"
import { useFormik } from "formik"
import * as Yup from "yup"
const validate = Yup.object({
name: Yup.string().max(15, "名前は15文字までです").required("名前必須"),
email: Yup.string().email("Eメールアドレスが無効です").required("メールアドレス必須"),
})
const SignupForm = () => {
const formik = useFormik({
initialValues: {
name: "",
email: "",
},
validationSchema: validate,
onSubmit: values => {
alert(JSON.stringify(values, null, 2))
}
})
return (
<form
onSubmit={formik.handleSubmit}
autoComplete="off"
>
<div className="w-25 mx-auto my-3">
<label htmlFor="name">名前</label>
<input
id="name"
name="name"
type="text"
onChange={formik.handleChange}
value={formik.values.name}
onBlur={formik.handleBlur}
className="form-control"
/>
{ formik.touched.name &&
formik.errors.name ?
<div className="text-danger">
{formik.errors.name}
</div> :
null
}
</div>
<div className="w-25 mx-auto my-3">
<label htmlFor="email">
メールアドレス
</label>
<input
id="email"
name="email"
type="email"
onChange={formik.handleChange}
value={formik.values.email}
onBlur={formik.handleBlur}
className="form-control"
/>
{ formik.touched.email &&
formik.errors.email ?
<div className="text-danger">
{formik.errors.email}
</div> :
null
}
</div>
<div className="w-25 text-center mx-auto">
<button
type="submit"
className="btn btn-primary w-100 my-3"
>Submit</button>
</div>
</form>
)
}
export default SignupForm