2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

FlutterのBLoCパターンについての説明

Last updated at Posted at 2020-10-13

Flutterの状態管理手法のBLoCパターンを学習したのでアウトプットする。

重要な前提

**知識面についてはこちらの記事を読めばほぼ解決します。**私はQiita書き終わってから気づきました。

本記事が提供するもの

これで終了なのだが、せっかくなので私が学んだことをアウトプットしてみる。

前提

  • 現在BLoCパターンは、Flutterの状態管理手法として最適とは考えられていない
  • 実用ではProvider, RiverPod等を用いるのが主流であると思う。
  • 状態管理手法の学習はInheritedWidget使用から始めるのがよいのだと思う。InheritedWidgetをラップしたのが前述のProviderである
  • BLoCパターンを体系的に学習する際は本記事ではなく、こちらを参照するのがよい。

BLoCパターンについての私の理解

  • BLoCパターンはWidget Treeとビジネスロジック(BLoC)をきれいに分離できてよい。
  • 分離の仕組みを以下に記す。

BLoCとWidgetTreeの関係

  • ボタンを押す等の操作時にWidgetからBLoCに情報を伝える
  • BLoCがその情報をWidgetに伝える
  • (情報を受け取ったWidgetがStreamBuilder等で表示を更新する)

BLoC全体
出典: すめだブログ FlutterのBLoCパターンについて得た知見

BLoCの中身

  • Sinkで情報を受取る
  • Streamで情報を流す

BLoC
出典: Getting Started with the BLoC Pattern

サンプル: 最もシンプルなBLoCパターン活用例

以上で説明したように、BLoCそのものは単純な仕組みである。最も単純なBLoC利用サンプルを見つけたので紹介する。

ただしアプリの構成が複雑になるとBLoCを利用する工夫が必要になってきて、そこが複雑になりうる。

BLoCProvider = BLoCパターンを利用する場合の工夫

上に述べたものが恐らくBLoCパターンの全貌であるが、Widget Treeの階層がある場合は、以下の問題に対処する必要がある。

配下のWidgetからBLoCを利用できるようにするため、以下の対応が必要になる。

  • あるWidgetでBLoCを保持する
  • 配下のWidgetからBLoCがアクセス可能にする

また、あるWidgetでBLoCを保持するため、以下の対応が必要になる。

  • BLoCを保持するWidgetが破棄された際に、BloC内のstreamをcloseする

そこでBLoCProviderと呼ばれる仕組みが必要になる。
上述のシンプルな例はBloCを使うのは1階層のStatelessWidget内なので、ここで挙げた対応は不要であり、BLoCProviderは必要ない。

BLoCProvider

BLoCを使う配下の階層を持つ構成では、以下の処理をするような仕組みが必要になる。

  • あるWidgetでBLoCを保持する
  • 配下のWidgetからBLoCへのアクセスを可能にする
  • BLoCを保持するWidgetが破棄された際に、BloC内のstreamをcloseする

チュートリアルではStatefulWidgetであるBlocProvider クラスがそれを担っている。この BlocProvider クラスは、以下の方法で問題に対応している。

  • プロパティとしてBLoCを保持する
  • findAncestorWidgetOfExactType で配下のWidgetからアクセス可能にする
  • dispose() 内でStreamControllerclose()する

dispose() を利用するためにStatefulWidgetにしたというわけだ。

計算量O(N)の解決

上述の方法の問題点として、findAncestorWidgetOfExactType の計算量がO(N)であることが挙げられる。これによってWidgetTreeの規模が大きくなるとパフォーマンスが悪くなるのだ。

これを解決して、BlocProviderにO(1)でアクセスするには、さらにInheritedWidgetを組み込んだ仕組みにするとよい。

そのためのライブラリとして bloc_providerがある。
また、以下の用にProviderと併用する方法もあるようだ。
Flutter BLoC+Providerとマルチプロバイダーのサンプル(戻るボタンのフックで苦労した話)

まとめ

さらにまとめ

  • こちらの記事を読めば全部解決できることに気づいた。
  • この記事にあるように、現在のスタンダードはBLoCではなくprovider + ChangeNotifierと考えてよいと思う。ただしこちらの詳しい解説は本稿の範囲外とする。
2
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?