FELTE:反応のための拡張可能な形式ライブラリ


NOTE: The previous articles in the series have been updated for v1!


おそらく、問題解決のために必要なフロントエンドの開発者は、最も一般的な問題の一つです.特に、ユーザーとの即時の妥当性検査と他のリアルタイムの相互作用を必要とする現代のWebアプリケーションで.可能な限り最高のユーザーエクスペリエンスを提供するには、おそらくあなたを助けるためにサードパーティ製のフォーム管理ライブラリをつかむでしょう.
このポストでは、私は約書くつもりですFelte , あなたの要件が成長するにつれて複雑に成長することを可能にしながら、私は、私はフロントエンドでフォームの処理の基礎を可能な限り簡単にすることを目指して、過去1年間の作業のためのフォーム管理ライブラリのために取り組んでいる.
これは、フェルトに関連する3つのブログ記事の一つです.これは、フェルトの統合に向けてReact . 他の2つとのフェルトの統合に向けているSvelte and Solid .

機能


前述のように、フェルトは、構成と拡張性を通してより複雑なふるまいを考慮に入れている間、可能な限り処理するのが簡単であるように、フォーム反応性の基礎を作ります.主な特徴は
  • あなたのフォームを無効にする単一のアクション.
  • HTML 5ネイティブ要素を使用してフォームを作成します.のみname 属性が必要です).
  • 最小再生産コンポーネントにフォームのデータを必要としない場合はNoneです.
  • より複雑なユースケースを扱うために、ストアとヘルパー機能を提供します.
  • 検証戦略に関する仮定はありません.あなた自身の戦略を必要とするか、書くどんな検証ライブラリも使ってください.
  • 実行中のフォームのコントロールの追加と削除を処理します.
  • エラー報告のための公式ソリューションreporter パッケージ.
  • サポートの検証yup , zod , superstruct and vest .
  • 容易にextend its functionality .
  • どうやって見えるの?


    最も基本的な形式では、フェルトは1つだけインポートする必要があります.
    import { useForm } from '@felte/react';
    
    export function Form() {
      const { form } = useForm({
        onSubmit: (values) => {
          // ...
        },
      });
    
      return (
        <form ref={form}>
          <input type="text" name="email" />
          <input type="password" name="password" />
          <input type="submit" value="Sign in" />
        </form>
      );
    }
    
    我々は、呼び出しによってフォームを設定しましたuseForm 我々とsubmit ハンドラ.この関数は、他のユーティリティのうち、フォーム要素で使用できるアクションを返します.今フェルトは、すべての入力を追跡するname 属性.フォームを送信するときは、入力の最新値をonSubmit オブジェクトとして機能する.前の例では、values になります.
    {
      email: '',
      password: '',
    }
    

    私のデータはどこで見られますか。


    あなたがタイプするように、FELTEはあなたのユーザーデータのあなたのフォームデータをあなたのonSubmit . この観測可能性はFelteによって処理され、その値は関数data からuseForm ; 自分でオブザーバーを扱う必要はありません!これらの関数をaccessors これから.このアクセサーが引数なしで呼び出されたとき(data() ), フォームのデータの全てをオブジェクトとして返します.これはまた、フォームを変更するたびにコンポーネントを「サブスクリプション」し、値を変更するたびに再描画をトリガします.引数は、最初の引数として渡すことができます.引数を使用すると、コンポーネントは、選択した特定の値に対して変更された「購読」だけになります.
    たとえば、コンソールにユーザーのメールをログ出力します.
    // Within a component
    const { form, data } = useForm({ /* ... */ });
    
    // Passing a function as first argument
    console.log(data(($data) => $data.email));
    
    // Passing a string as first argument
    console.log(data('email'));
    

    Accessors are NOT hooks, this means they can be called from wherever you need them in your code.


    ここでバリデーションが必要かもしれません


    もちろん、フォームの別の一般的な要件は妥当性検査です.我々は我々のアプリは、ユーザーに強打を感じるようにする場合は、いくつかのクライアント側の検証が必要になります.useForm ’s設定オブジェクトはvalidate 関数(非同期である).それはあなたの現在の値を受け取りますdata それが変化して、フォームが有効でないならば、あなたの検証メッセージを含む同じ形でオブジェクトを返すと予想します、あるいは、あなたの形が有効な場合は何もありません.Felteは、これらの検証メッセージをuseForm ASerrors :
    const { form, errors } = useForm({
      validate(values) {
        const currentErrors = {};
        if (!values.email) currentErrors.email = 'Must not be empty';
        if (!values.password) currentErrors.password = 'Must not be empty';
        return currentErrors;
      },
    });
    
    console.log(errors(($errors) => $errors.email));
    
    より複雑な検証要件は第三者検証ライブラリを必要とするかもしれません.フェルトは、拡張機能を介していくつかの人気の検証ライブラリとの最初のパーティーの統合を提供しています.これらの統合は別々のパッケージとして提供されます.次の節では、拡張性についての記述を書きますが、これらのパッケージについての詳細はofficial documentation .

    拡張性による複雑なシナリオのハンドリング


    フェルトは、フォーム管理に関するすべてのシナリオを処理する方法についての完全な解決策を試みません.そういうわけで、Felteはあなたの要件がより複雑になるので、その機能を広げるAPIを提供します.あなたは本当に人気のような使用するような好みのライブラリがありますyup , or Vest (最近では話題になっていた).これらのシナリオを処理するフェルトの振る舞いを変更することはextend オプションuseForm ’s設定オブジェクト.これについての詳細はofficial documentation . このブログ記事の目的のために単純なものを保つために、私はいくつかの一般的なユースケースを扱うために維持する既存のパッケージについて書きます.

    バリデータ:人気の検証ライブラリとの統合


    私たちは現在、4つのパッケージを維持しています.yup , zod , superstruct 最近ではvest . ここでは、例としてYUPを使用しますが、残りについての詳細を読むことができますhere .
    使用するパッケージyup NPMの名前の下にあります@felte/validator-yup . 一緒にインストールする必要がありますyup :
    npm install --save @felte/validator-yup yup
    
    # Or, if you use yarn
    
    yarn add @felte/validator-yup yup
    
    このバリデータパッケージは、関数validator 検証スキーマを呼び出し、その結果をextend オプションuseForm :
    import { validator } from '@felte/validator-yup';
    import * as yup from 'yup';
    
    const schema = yup.object({
      email: yup.string().email().required(),
      password: yup.string().required(),
    });
    
    const { form } = useForm({
      // ...
      extend: validator({ schema }), // OR `extend: [validator({ schema })],`
      // ...
    });
    

    リポーター:検証メッセージの表示


    確認メッセージを表示するには、errors 返されるアクセサーuseForm . 関連するフィールドが相互作用するまで、メッセージはこのアクセサーで利用できません.
    import { useForm } from '@felte/react';
    
    function Form() {
      const { form, errors } = useForm({ /* ... */ });
    
      return (
        <form ref={form}>
          <label htmlFor="email">Email:</label>
          <input name="email" type="email" id="email" />
          {!!errors('email') && (
            <span>{errors('email')}</span>
          )}
          <button>Submit</button>
        </form>
      );
    }
    

    If a specific field has an error, Felte assigns an aria-invalid=true attribute to the appropriate input.


    しかし、検証メッセージを処理する特定の構文が気に入らないかもしれません.Felteには、検証メッセージを表示する方法について別の選択肢を提供する4つのパッケージがあります.
  • 最も柔軟性があり、コンポーネントツリー内の深さの検証メッセージへのアクセスを許可するerrors アクセサーアラウンド.
  • DOM要素の追加と削除によってDOMを直接変更すること.
  • Tippyの使用JSはあなたのメッセージをツールチップに表示します.
  • ブラウザーのビルトイン制約検証APIを使用することは、モバイルユーザにあまり友好的でありえません.
  • 簡潔さのために、私は最初のパッケージをカバーするだけです.しかし、あなたは残りについての詳細を読むことができますin the documentation .
    確認コンポーネントを使用して検証メッセージを取得するには@felte/reporter-react . お気に入りのパッケージマネージャーを使用してプロジェクトに追加する必要があります.
    # npm
    npm i -S @felte/reporter-react
    
    # yarn
    yarn add @felte/reporter-react
    
    その後、両方をインポートする必要がありますreporter 関数を追加するextend プロパティとValidationMessage 検証メッセージを受け取るために使用するコンポーネント
    import { reporter, ValidationMessage } from '@felte/reporter-react';
    import { useForm } from '@felte/react';
    
    function Form() {
      const { form } = useForm({
          // ...
          extend: reporter, // or [reporter]
          // ...
        },
      })
    
     // We assume a single string will be passed as a validation message
     // This can be an array of strings depending on your validation strategy
      return (
        <form ref={form}>
          <input id="email" type="text" name="email" />
          <ValidationMessage for="email">
            {(message) => <span>{message}</span>}
          </ValidationMessage>
          <input type="password" name="password" />
          <ValidationMessage for="password">
            {(message) => <span>{message}</span>}
          </ValidationMessage>
          <input type="submit" value="Sign in" />
        </form>
      );
    }
    

    次の手順


    あなたはフェルトについての詳細をチェックすることができますofficial website いくつかの機能例で.また、より複雑な例では、その使用法をティッピーで紹介しています.JSとYUPの利用可能CodeSandbox .

    仕上げ思考


    私は、これがフェルトに良い紹介として役立って、それはあなたがそれを試してみるのに十分興味深いと思います.フェルトはすでに安定した状態で、一部の人々によって使用されます.私はまた、ヘルプや提案を開きますので、問題を開くか、またはプル要求を無料で気軽にGitHub .