【React/Formik】入力時に自動送信する方法

React

Formikを使用しているときに、入力に合わせて自動送信させたかったので、調べて実装してみました。

方針

FormikのuseFormikContextを使用する!
FormikのForm内の子コンポーネント等で呼び出すと、Formikの変数や関数を取得することができますvalues, submitForm, isValidなど色々取得できます!

コード例

onSubmitを実行させる場合

useFormikContextからsubmitForm関数も取得できるので、それを実行させます。

import React, {useEffect} from 'react';
import { useFormikContext, Formik, Form, Field } from 'formik';
 
type FormValues = {
  name: string
  email: string
}

 const AutoSubmitToken = () => {
   const { values, submitForm } = useFormikContext<FormValues>(); // ココ。TypeScriptでない場合は<>内は不要。
   useEffect(() => {
     if (/^[a-zA-Z0-9_+-]+(.[a-zA-Z0-9_+-]+)*@([a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9]*\.)+[a-zA-Z]{2,}$/.test(values.email)) {
       submitForm(); // ココ
     }
   }, [values.email]); // values.emailに変更があったときにuseEffectが動く
   return null;
 };
 
 const ExampleForm = () => (
   <div>
     <Formik
       initialValues={{ name: '', email: '' }}
       onSubmit={(values: FormValues) => {alert(`name: ${values.name}, email: ${values.email}`)}}
     >
       <Form>
         <Field name="name" />
         <Field name="email" type="email" />
         <AutoSubmitToken />
       </Form>
     </Formik>
   </div>
 );

任意の関数を実行させる場合

実行関数をpropとして渡せば、任意の関数の実行もできます。

import React, {useEffect} from 'react';
import { useFormikContext, Formik, Form, Field } from 'formik';
 
type FormValues = {
  name: string
  email: string
}

 const AutoSubmitToken: React.FC<{submitHandler: (arg: string)=>void}> = ({submitHandler}) => {
   const { values } = useFormikContext<FormValues>(); // ココ。TypeScriptでない場合は<>内は不要。
   useEffect(() => {
     if (/^[a-zA-Z0-9_+-]+(.[a-zA-Z0-9_+-]+)*@([a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9]*\.)+[a-zA-Z]{2,}$/.test(values.email)) {
       submitHandler(values.email);
     }
   }, [values.email]); // values.emailに変更があったときにuseEffectが動く
   return null;
 };
 
 const ExampleForm: React.FC = () => {
  const submitEmail = (email: string): void => {
    alert(`valid email: ${email}`)
  }

  return (
   <div>
     <Formik
       initialValues={{ name: '', email: '' }}
       onSubmit={(values: FormValues) => {alert(`name: ${values.name}, email: ${values.email}`)}}
     >
       <Form>
         <Field name="name" />
         <Field name="email" type="email" />
         <AutoSubmitToken submitHandler={submitEmail} />
       </Form>
     </Formik>
   </div>
   );
}
タイトルとURLをコピーしました