torikatsu923.dev

サイト内検索

    Blocパターンでのフォームバリデーション

    最近、Flutterでアプリ開発をしているのですが、Blocパターンでフォームのバリデーションのスマートな実装方法についてまとめられた記事があまりなく、どハマりしました。

    最近、Flutterでアプリ開発をしているのですが、Blocパターンでフォームのバリデーションのスマートな実装方法についてまとめられた記事があまりなく、どハマりしました。

    そこで今回の記事では、BlocパターンでRxDartを用いたスマートなフォームのバリデーションの実装方法をサインインページを例として紹介したいと思います。

    記事の対象:

    Rx・flutter初心者

    得られる情報

    Blocを使ったフォームの実装方法

    サインインページの要件は以下の通りとします。

    • メールアドレス

      @を含む1文字以上の文字列

    • パスワード

      8文字以上の英数字からなる文字列

    ※はてなのシンタックスハイライトが弱いので、今回はあえてスクリーンショットを用いてコードを掲載します。

    1. UIを用意する

    まずUIを用意します。今回はパスワードとメールの入力欄+送信ボタンのシンプルな構成とします。

    用意したUI

    2. Blocを用意する

    今回は以下のようなBlocクラスを用意します。

    ポイントはBehaviorSubjectを使うところです。 BehaviorSubjectはイベントをキャッシュしておいてくれるので、過去のイベントに対し、BehaviorSubject.valueでアクセスできます。 

    そのため入力情報を保持しておくフィールドを用意しなくてすみます。

    Bloc

    Blocでは全ての入出力をStreamにするべきだとありますが、ここではあえてそのルールを破りsubmitをパブリックなメソッドとして定義しています。

    なぜならば、ストリームでsubmitを定義すると送信ボタンのonPressedが冗長になってしまうからです。

    ストリームで実装すると以下のように冗長な書き方になりますが、

    onPressed: () => bloc.submit(null)

    メソッドで定義しておくと

    onPressed: bloc.submit

    と定義でき、UI側のコードがすっきりします。

    UIにBlocを注入する

    Providerを使ってUIにBlocを注入します。
    ついでにTextFieldとRaisedButtonにコールバックを渡します。

    BlocをUIに注入

    Providerはウィジェットの生成と破棄に合わせた処理を渡しておけるので便利です。

    ここでProviderの直下にBuilderを配置していますが、これはこのクラス内からProvider.of(context)でBlocにアクセスするためです。

    なぜBuilderを挟む必要があるのかについてはまたいずれ記事にしたいと思います。

    バリデーションの実装

    いよいよバリデーションを実装していきます。 UI側にバリデーションの結果を伝えるためにStream.addErrorとRx.combineStreamを使います

    以下はバリデーションを追加したBlocクラスです。

    バリデーション追加後のBloc

    ポイントはRx.combineLatestを使用することです。 これを使わずに送信ボタンにバリデーションの結果を通知するストリームを用意してもいいのですが、新しくストリームを生成しなければならないうえ、closeもしなくてはなりません。

    今回のケースでは気になりませんが、Streamの数が増えるほどStreamの管理がしんどくなってくるので、combineLatestを使った方がスマートだと思います。

    UIでバリデーションの結果を受け取る

    UIでバリデーションの結果を受け取るにはInputDecorationクラスのerrorTextを利用します。

    StreamBuilderで入力情報のストリームをリッスンしておき、エラーが流れてきたらsnapshot.errorがエラーテキストとして表示されると言った感じです。

    また送信ボタンもバリデーションの結果を受け取れるようにしておきます。

    UIでバリデーションの結果を受け取る

    コード全体像

    コードの全体像は以下の通りです。 UI

    UI全体

    UI全体

    おわりに

    今回フォームの実装方法を探る中で、Rxdartのコードを読みました。英語が苦手で過ごし面食らいましたが、じっくり読んでみるとかなり丁寧にコメントがされていて、ネットの情報見るよりわかりやすかったので、もし困ったらコードのコメントを読むのをお勧めします。

    -––