react 初心者がいろいろ学んだことやハマったことの記録。
formik 編。(typescript使って実装してます)
react + formik + Yup を使って動的なバリデーション実装するのにuseFormikというフックを使ってみた
通常は、Formikコンポーネントを用いて実装しますが、諸事情でreact要素以外でformikを使いたいケースがあったため、useFormik使ってみることにしました。
ところが、FormikのErrorMessageコンポーネントでバリデーションエラーが出せないどころか、formikがundefinedだというエラーが発生してしまいました。
import React, {useState} from 'react';
import {useFormik, ErrorMessage} from 'formik';
import {FormikValuesProps} from './types';
import {createValidationSchema} from './validation-schema';
const HogeComponent: React.FC = () => {
const formik = useFormik<FormikValuesProps>({
initialValues: {
firstName: '',
lastName: '',
},
// 動的なValidationShema生成(詳細は割愛..)
validationSchema: createValidationSchema(...),
onSubmit: () => {},
});
return (
<>
<label htmlFor="firstName">First Name</label>
<input
type="text"
name="firstName"
value={formik.values.firstName}
/>
{/** ここでエラーになる */}
<ErrorMessage name="firstName" />
......
</>
);
};
export default HogeComponent;
原因は
ErrorMessageはReact Contextを介してformikにアクセスする。
useFormikが返すformikはContextに存在しない。(FormikContextは生成されない)
Formik公式サイトを改めて眺めるとそのようなことが書かれています。英文のドキュメントがいまいち頭に入ってこないため、Formikコンポーネントのソースものぞいみたところ、useFormikで取得したformikをContextに引き渡してコンポーネント生成していました。
ErrorMessageコンポーネントを使ってバリデーションエラーを表示したいのであれば、FormikContextにuseFormik が返すformikを渡せばいいのだな、ということはわかりました。
どうしたか
チュートリアルに、プロバイダを使用してFormikContextにformikに引き渡しているコードがあったのでそちらを参照しつつ、コードを修正してみます。
import React, {useState} from 'react';
import {useFormik, ErrorMessage, FormikContext} from 'formik';
...
const HogeComponent: React.FC = () => {
// 省略
return (
{/** こちらを追加 */}
<FormikContext.Provider value={formik}>
<input
type="text"
name="firstName"
value={formik.values.firstName}
/>
<ErrorMessage name="firstName" />
......
</FormikContext.Provider>
);
};
これで、無事ErrorMessageコンポーネントを使ってバリデーションエラーを表示させることができました。
参照サイト
Formik公式サイト - https://jaredpalmer.com/formik
React公式サイトのContext - https://ja.reactjs.org/docs/context.html