これ以上の涙は、Formeikを使用して反応の処理フォーム、パート2


私に従って、トピックや改善についてのご提案を取るに満足

This is the continuation of our first part on Formik, the amazing Forms library for React


この記事はシリーズの一部です.

  • これ以上の涙は、Formeikを使用して反応の処理の形態、パート2、我々はここにいる
  • この記事では以下を説明します.

  • YUPを使用したスキーマ検証では、入力要素を検証する別の方法があります.YUPでスキーマを宣言するだけで、FormIkコンポーネントの

  • 非同期確認

  • 内蔵のコンポーネントは、すべてのコンポーネントをいくつかのFormulksの組み込みコンポーネントを使用して冗長です
  • リソース


    私は両方のこれらの記事のためにレポを作ったので、あなたが立ち往生するならば、見てくださいForm demo repo

    組み込みコンポーネント


    これまでのところ、通常のHTML要素を使用していますform and input 造るform そして、我々はイベントのように接続しているonSubmit , onChange and onBlur . しかし、我々は実際に多くの少ない入力することができます.次のコンポーネントによろしく

  • フォームは、通常のform 元素

  • フィールドでは、input 元素

  • ErrorMessage、これは本当にあなたが持っているどんなコントロールも交換しませんが、属性を与えられるすばらしい構成要素ですname エラーメッセージを表示することができます
  • まず、簡単なフォームを見て、上記のコンポーネントを使って書き直しましょう.
    import { Formik } from 'formik';
    import React from 'react';
    
    const FormikExample = () => (
      <Formik
        initialValues={{ name: '' }}
        validation={values => {
          let errors = {};
          if(!values.name) {
            errors.name = 'Name is required';
          }
          return errors;
        }}
        onSubmit={values ={
          console.log('submitted');
        }}
      >
      {({ handleSubmit, handleChange, values, errors }) => (
       <form onSubmit={handleSubmit}>
        <input name="name" onChange={handleChange} value={values.name} />
        {errors.name && 
        <span>{errors.name}</span>
        }
       </form>
      )
      }
      </Formik>
    )
    
    を参照してください.上記のように、最小限の実装が古典的な方法のように見えますform and input .
    では、組み込みのコントロールを使用してこれをきれいにしましょう.
    import { Formik, Form, Field, ErrorMessage } from 'formik';
    import React from 'react';
    
    
    const FormikExample = () => (
      <Formik
        initialValues={{ name: '' }}
        validation={values => {
          let errors = {};
          if(!values.name) {
            errors.name = 'Name is required';
          }
          return errors;
        }}
        onSubmit={values ={
          console.log('submitted');
        }}
      >
      {({ handleSubmit, errors }) => (
       <Form onSubmit={handleSubmit}>
        <Field type="text" name="name" />
        <ErrorMessage name="name"/>
        }
       </Form>
      )
      }
      </Formik>
    )
    
    スーパー感動?次のように入力する必要はありません.
  • the onChange それぞれから消えるinput 元素
  • the input 要素を置換Field コンポーネント
  • the form 要素を置換Form コンポーネント
  • 条件{errors.name && だけでなくErrorMessage コンポーネントはそのビットの世話をする
  • 十分でない?あなたが10のフィールドを持っていると想像してください.我々の次の改善に、我々は我々を取り替えることができますvalidation() との機能schema , 次へ.

    YUPによるスキーマ検証


    を、私たちは本当に私たちは本当にビルトインコントロールを使用してマークアップをクリーンアップする方法をカバーしてきたForm , Field and ErrorMessage . 次のステップは、私たちを置き換えることによってさらに改善されますvalidation プロパティvalidationSchema プロパティ.そのためには、ライブラリyupを使ってスキーマを定義する必要があります.では、スキーマは次のようになります.
    import * as Yup from 'yup'
    
    const schema = Yup.object().shape({
        firstName: Yup.string()
          .min(2, 'Too Short!')
          .max(50, 'Too Long!')
          .required('Required'),
        lastName: Yup.string()
          .min(2, 'Too Short!')
          .max(50, 'Too Long!')
          .required('Required'),
        email: Yup.string()
          .email('Invalid email')
          .required('Required'),
      });
    
    上記のスキーマは3つの異なるフィールドを定義しますfirstName , lastName and email そしてそれぞれの属性を与えなければなりません:

  • firstname、これは最小2文字と最大50文字から成る文字列でなければなりません

  • last nameこれは、同じMIN/MAX要件の文字列でもあり、

  • 電子メール、これは必要な文字列です
  • あなたが見ることができるように、上記は非常に読みやすく、このようなデータを定義することによってif すべての属性が満たされているかどうかをチェックします.
    では、私たちの中で使用しましょうFormik 以下のような要素:
    <Formik validationSchema={schema}>
    
    つまり、あなたのフォームデータを本当に表現的な方法で定義する必要があるのです.

    非同期確認


    を、最後のトピックには、非同期の妥当性を確認します.それで、シナリオは何ですか?よく、時には、本当に入力された値が正しいかどうかだけではなく、クライアント側に伝えることができないデータがあります.あなたが会社や特定のWebページのドメインが既に取られているかどうかを確認するフォームを想像してみませんか?その時点で、おそらくあなたはエンドポイントへの呼び出しを行う必要がありますエンドポイントは即座に答えを返すことはありません.
    を、我々はシーンを設定して、どのように我々はFormekでこれを解決するのですか?まあ、validation プロパティは、同様に約束を受け入れることができます.本当に、あなたは思う?簡単?さて、解決策は私の心に少し正統的なものです.
    <Formik
      validate={values => {
        console.log('validating async');
        let errors = {};
        return new Promise((resolve, reject) => {
          setTimeout(() => {
            errors.companyName = 'not cool';
            resolve('done');
          },3000);
          }).then(() => {
            if(Object.keys(errors).length) {
              throw errors;
            }
          });
        }}
    >
    // define the rest here
    </Formik>
    
    我々を見ることvalidate 実装では、内部で実行されるsetTimout それはエンドポイントには、答えを得るために時間がかかることをシミュレートする.この時点で我々はerrors.companyName を返します.
    setTimeout(() => {
      errors.companyName = 'not cool';
      resolve('done');
    },3000);
    
    もっと現実的なシナリオでは、おそらく関数を呼び出して、おそらく我々が割り当てるかもしれない関数の答えに応じてerrors.companyName . 私の言いたいことを以下に示します.
    isCompanyNameUnique(values.companyName).then(isUnique => {
      if(!isUnique) {
        errors.companyName = `companyName is not unique, please select another one`
      }
      resolve('done')
    })
    
    我々のコードで起こる次のことは、我々が起動するということですthen() , 我々が呼ぶとき、それは起こりますresolve() . 何か本当に面白いことが起こって、我々はerrors 設定されている可能性のあるプロパティに対して、もしエラーが発生した場合はerrors 引数としてのオブジェクトです.
    .then(() => {
      if(Object.keys(errors).length) {
        throw errors;
      }
    });
    
    私はあなたについて知りません、しかし、私にとって、これは少し変に見えます.私は、提供を考えましたvalidation 約束があればそれはreject() このような約束は、より直感的なやり方で行いました.
    // this to me would have been more intuitive, but observe, this is NOT how it works, so DONT copy this text but refer to the above code instead
    
    validation={ values => 
      console.log('validating async');
      let errors = {};
      return new Promise((resolve, reject) => {
        setTimeout(() => {
          errors.companyName = 'not cool';
          reject(errors);
        },3000);
      })
    }}
    

    フィールドレベルの非同期


    今までのところ、フォームレベルでの非同期の妥当性検査を行う方法を示しましたが、あなたが考えるならば、あなたは本当にそれを望みますか?フィールドが混在している可能性があります.フィールドが混在していれば、クライアント側のいくつかを検証するのに十分です.このような場合、フィールドごとに妥当性検査を適用することは意味があります.これは以下のように入力することでとても簡単です.
    <Field name="username" validate={this.validate} >
    
    フィールドでの非同期の妥当性検査を行った場合、おそらくこれが望ましいでしょう.他のフィールドについては、クライアント側を検証することができますFormik コンポーネントvalidationSchema 使用Yup 上で述べたようなスキーマです.

    用心深い言葉


    もし、検証が時間がかかる場合は、特に確認してください.キーが入力されるたびに、3秒のバリデーションをトリガする必要はありません.ユーザーがフィールドを別のフィールドで入力を開始するときに、ほとんどの場合、それを望みますblur イベント.だからあなたを設定してくださいFormik 以下のようなコンポーネント:
    <Formik
      validateOnBlur={true} 
      validateOnChange={false} >
    
    これはあなたが望むもの、設定validateOnBlur to true これは技術的にもtrue デフォルトでは.あなたは次のいずれかを明示的にしたいvalidateOnChange . これをオフにするか、またはfalse .

    概要


    我々は、ビルトインのコンポーネントをカバーするように設定しましたForm , Field and ErrorMessage , 最後の結果は私たち多くのコードをクリーンアップされた.
    さらに、この関数を用いてスキーマを定義することによって、検証機能を削除する方法を示したYup 図書館.
    最後に、非同期妥当性検査をカバーし、検証するときのように考慮するようにして、フォーム内のいくつかの非同期フィールドに対してフィールドレベルの検証を実行し、残りのフィールドにスキーマ検証を使用するのが最善でしょう.
    それが私たちの記事の終わりだった.私は、この部分と前のものがあなたに新しい反応を与えたことを望みます